写在前面
本文假定你已对Numpy和Pandas有所了解
这次向大家介绍一下Pandas中四大重要的对象
Series\DataFrame\Index\MultiIndex
欢迎大家到我的个人博客闲逛https://syjun.vip
我们先做一个约定,约定你代码的第一行
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
Series
Series属性及方法
- Series一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率.
一个简单的列子
ser1=Series([4,12,-12,-4])
ser1
代码结果
0 4
1 12
2 -12
3 -4
dtype: int64
ser2=Series([4,12,-12,-4],index=['b','c','a','d'])
ser2
代码结果
b 4
c 12
a -12
d -4
dtype: int64
values和index
- Series有两个很最要的属性values和index,分别获取内容和索引
values
ser1.values
代码结果
array([ 4, 12, -12, -4], dtype=int64)
index
ser1.index
代码结果
RangeIndex(start=0, stop=4, step=1)
可将字典转换为Series
dict={"red":100,"black":400,"green":300,"pink":900}
ser3 = Series(dict)
ser
代码结果
black 400
green 300
pink 900
red 100
dtype: int64
pandas的isnull和nonull可检测缺失数据
isnull
pd.isnull(ser3)
代码结果
purple False
brown False
glod False
blue False
Name: values, dtype: bool
### notnull ###
pd.notnull(ser3)
代码结果
purple True
brown True
glod True
blue True
Name: values, dtype: bool
DataFrame
DataFrame 是 Python 中 Pandas 库中的一种数据结构,是一种二维表。它类似 excel,或许说它可能有点像 matlab 的矩阵,但是 matlab 的矩阵只能放数值型值(当然 matlab 也可以用 cell 存放多类型数据),DataFrame 的单元格可以存放数值、字符串等,这就和 excel 表很像。
一、DataFrame对象常用属性
- 创建DateFrame方法有很多(后面再介绍),最常用的是直接传入一个由等长列表或Numpy组成的字典:
dict1={"Province":["Guangdong","Beijing","Qinghai","Fujiang"],
"year":[2018]*4,
"pop":[1.3,2.5,1.1,0.7]}
df1=DataFrame(dict1)
df1
代码结果:
|
Province |
year |
pop |
0 |
Guangdong |
2018 |
1.3 |
1 |
Beijing |
2018 |
2.5 |
2 |
Qinghai |
2018 |
1.1 |
3 |
Fujiang |
2018 |
0.7 |
- 同Series一样,也可在创建时指定序列(对于字典中缺失的用NaN):
df2=DataFrame(dict1,
columns=['year','Province','pop','debt'],
index=['one','two','three','four'])
df2
代码结果:
|
Province |
year |
pop |
debt |
one |
Guangdong |
2018 |
1.3 |
NaN |
two |
Beijing |
2018 |
2.5 |
NaN |
three |
Qinghai |
2018 |
1.1 |
NaN |
four |
Fujiang |
2018 |
0.7 |
NaN |
- 同Series一样,DataFrame的index和columns有name属性:
df2.index.name='English'
df2.columns.name='Province'
df2
代码结果
Province |
Province |
year |
pop |
debt |
English |
|
|
|
|
one |
Guangdong |
2018 |
1.3 |
NaN |
two |
Beijing |
2018 |
2.5 |
NaN |
three |
Qinghai |
2018 |
1.1 |
NaN |
four |
Fujiang |
2018 |
0.7 |
NaN |
- 通过shape属性获取DataFrame的行数和列数:
df2.shape
代码结果:
(4, 4)
- values属性也会以二维ndarray的形式返回DataFrame的数据:
df2.values
代码结果:
array([['Guangdong', 2018 , 1.3, nan],
['Beijing', 2018 , 2.5, nan],
['Qinghai', 2018 , 1.1, nan],
['Fujiang', 2018 , 0.7, nan]], dtype=object)
二、DataFrame对象常见存取、赋值和删除方式
- DataFrame_object[ ] 能通过列索引来存取,当只有一个标签则返回Series,多于一个则返回DataFrame:
df2['Province']
代码结果:
English
one Guangdong
two Beijing
three Qinghai
four Fujiang
Name: Province, dtype: object
df2'Province','pop'
代码结果:
Province |
Province |
pop |
English |
|
|
one |
Guangdong |
1.3 |
two |
Beijing |
2.5 |
three |
Qinghai |
1.1 |
four |
Fujiang |
0.7 |
- DataFrame_object.loc[ ] 能通过行索引来获取指定行:
df2.loc['one']
year 2018
Province Guangdong
pop 1.3
debt NaN
Name: one, dtype: object
df2.loc['one':'three']
代码结果:
Province |
Province |
year |
pop |
debt |
English |
|
|
|
|
one |
Guangdong |
2018 |
1.3 |
NaN |
two |
Beijing |
2018 |
2.5 |
NaN |
three |
Qinghai |
2018 |
1.1 |
NaN |
df2.loc['one','Province']
代码结果:
'Guangdong'
- DataFrame的列可以通过赋值(一个值或一组值)来修改:
df2["debt"]=np.arange(2,3,0.25)
df2
代码结果:
Province |
Province |
year |
pop |
debt |
English |
|
|
|
|
one |
Guangdong |
2018 |
1.3 |
2.00 |
two |
Beijing |
2018 |
2.5 |
2.25 |
three |
Qinghai |
2018 |
1.1 |
2.50 |
four |
Fujiang |
2018 |
0.7 |
2.75 |
- 为不存在的列赋值会创建一个新的列,可通过del来删除:
df2['eastern']=None
df2
代码结果:
Province |
Province |
year |
pop |
debt |
eastern |
English |
|
|
|
|
one |
Guangdong |
2018 |
1.3 |
2.00 |
NaN |
two |
Beijing |
2018 |
2.5 |
2.25 |
NaN |
three |
Qinghai |
2018 |
1.1 |
2.50 |
NaN |
four |
Fujiang |
2018 |
0.7 |
2.75 |
NaN |
del df2['eastern']
df2.columns
代码结果:
Index(['year', 'Province', 'pop', 'debt'], dtype='object', name='Province')
三、多种创建DataFrame方式
- 调用DataFrame()可以将多种格式的数据转换为DataFrame对象,它的的三个参数data、index和columns分别为数据、行索引和列索引.data可以是:二维数组\字典\结构数组.
二维数组
df3=pd.DataFrame(np.random.randint(0,10,(4,4)),index=[1,2,3,4],columns=['A','B','C','D'])
df3
代码结果:
|
A |
B |
C |
D |
1 |
6 |
7 |
6 |
8 |
2 |
2 |
8 |
4 |
5 |
3 |
1 |
4 |
5 |
4 |
4 |
4 |
2 |
9 |
0 |
字典
值得注意的是行索引由index决定,列索引由字典的键决定
dict1 = {'Province': ['Guangdong', 'Beijing', 'Qinghai', 'Fujiang'],
'year': [2018, 2018, 2018, 2018]},
'pop': [1.3, 2.5, 1.1, 0.7]
df4=pd.DataFrame(dict1,index=[1,2,3,4])
df4
代码结果:
|
Province |
year |
pop |
0 |
Guangdong |
2018 |
1.3 |
1 |
Beijing |
2018 |
2.5 |
2 |
Qinghai |
2018 |
1.1 |
3 |
Fujiang |
2018 |
0.7 |
结构数组
其中列索引由结构数组的字段名决定
arr=np.array([('item1',10),('item2',20),('item3',30),('item4',40)],dtype=[("name","10S"),("count",int)])
df5=pd.DataFrame(arr)
df5
dtype里面的"10S"表示array里面元素里面的第一个值字符串长度不能超过10,否则不能正常显示
代码结果:
|
name |
count |
0 |
b'item1' |
10 |
1 |
b'item2' |
20 |
2 |
b'item3' |
30 |
3 |
b'item4' |
40 |
四、将DataFrame对象转换为其他格式的数据
- to_dict()方法将DataFrame对象转换为字典,参数orient决定字典元素的类型:
df3.to_dict()
#代码结果:
{'A': {1: 6, 2: 2, 3: 1, 4: 4},
'B': {1: 7, 2: 8, 3: 4, 4: 2},
'C': {1: 6, 2: 4, 3: 5, 4: 9},
'D': {1: 8, 2: 5, 3: 4, 4: 0}}
df3.to_dict(orient="records")
#代码结果:
[{'A': 6, 'B': 7, 'C': 6, 'D': 8},
{'A': 2, 'B': 8, 'C': 4, 'D': 5},
{'A': 1, 'B': 4, 'C': 5, 'D': 4},
{'A': 4, 'B': 2, 'C': 9, 'D': 0}]
df3.to_dict(orient="list")
#代码结果:
{'A': [6, 2, 1, 4], 'B': [7, 8, 4, 2], 'C': [6, 4, 5, 9], 'D': [8, 5, 4, 0]}
- 类似的还有to_records()、to_csv()等
Index
Index对象保存着索引标签数据,它可以快速找到标签对应的整数下标,其功能与Python的字典类似
dict1={"Province":["Guangdong","Beijing","Qinghai","Fujiang"],
"year":[2018]*4,
"pop":[1.3,2.5,1.1,0.7]}
df1=DataFrame(dict1)
df1
代码结果
|
Province |
year |
pop |
0 |
Guangdong |
2018 |
1.3 |
1 |
Beijing |
2018 |
2.5 |
2 |
Qinghai |
2018 |
1.1 |
3 |
Fujiang |
2018 |
0.7 |
- 调用.columns返回DataFrame对象的列索引即所有列标签
col_index=df1.columns
col_index.values
代码结果
array(['Province', 'pop', 'year'], dtype=object)
ind_index=df1.index
ind_index.values
#代码结果
array([0, 1, 2, 3], dtype=int64)
- Index对象可当做一维数组,适合Numpy数组的下标运算,但Index对象只是可读,创建后不可修改
print(col_index[[1,2]])
print(ind_index[ind_index>1])
#代码结果
Index(['pop', 'year'], dtype='object')
Int64Index([2, 3], dtype='int64')
- index对象具有字典的映射功能,.get_loc(value)获得单值得下标,.get_indexer(values)获得一组值得下标,当值不存在则返回-1:
print(col_index.get_loc('pop'))
print(col_index.get_indexer(['pop','year']))
#代码结果
1
[1 2]
- Index对象调用Index()来创建,可传递给DataFrame对象的参数index和columns。因为Index是不可变的,因此多个DataFrame对象的索引可以是同个Index对象
index=pd.Index(['a','b','c'])
df2=DataFrame(np.random.randint(1,10,(3,3)),index=index,columns=index)
df2
代码结果
|
a |
b |
c |
a |
4 |
1 |
2 |
b |
2 |
1 |
4 |
c |
5 |
2 |
0 |
MultiIndex
MultiIndex表示多级索引,它是从Index继承过来的,其中多级标签用元组对象来表示
一、创建MultiIndex对象
创建方式一:元组列表
m_index1=pd.Index([("A","x1"),("A","x2"),("B","y1"),("B","y2"),("B","y3")],name=["class1","class2"])
m_index1
代码结果
MultiIndex(levels=[['A', 'B'], ['x1', 'x2', 'y1', 'y2', 'y3']],
labels=[[0, 0, 1, 1, 1], [0, 1, 2, 3, 4]],
names=['class1', 'class2'])
df1 = Dataframe(np.random.randint(1,10,(5,3)),index = m_inex1)
df1
代码结果
创建方式二:特定结构
class1=["A","A","B","B"]
class2=["x1","x2","y1","y2"]
m_index2=pd.MultiIndex.from_arrays([class1,class2],names=["class1","class2"])
m_index2
代码结果
MultiIndex(levels=[['A', 'B'], ['x1', 'x2', 'y1', 'y2']],
labels=[[0, 0, 1, 1], [0, 1, 2, 3]],
names=['class1', 'class2'])
df2=DataFrame(np.random.randint(1,10,(4,3)),index=m_index2)
df2
代码结果
创建方式三:笛卡尔积
.from_product()从多个集合的笛卡尔积创建MultiIndex对象
m_index3=pd.MultiIndex.from_product([["A","B"],['x1','y1']],names=["class1","class2"])
m_index3
代码结果
MultiIndex(levels=[['A', 'B'], ['x1', 'y1']],
labels=[[0, 0, 1, 1], [0, 1, 0, 1]],
names=['class1', 'class2'])
df3 = pd.DataFrame(np.random.randint(1,10,(2,4)),columns = m_index3)
MultiIndex对象属性
我们再来看一下df1的结构
df1.loc[('A','x1'),2]
代码结果
2
m_index4=df1.index
print(m_index4[0])
代码结果
('A', 'x1')
- 调用.get_loc()和.get_indexer()获取标签的下标
print(m_index4.get_loc(("A","x2")))
print(m_index4.get_indexer([("A","x2"),("B","y1"),"nothing"]))
代码结果
1
[ 1 2 -1]
- MultiIndex对象使用多个Index对象保存索引中每一级的标签
print(m_index4.levels[0])
print(m_index4.levels[1])
代码结果
Index(['A', 'B'], dtype='object', name='class1')
Index(['x1', 'x2', 'y1', 'y2', 'y3'], dtype='object', name='class2')
- MultiIndex对象还有属性labels保存标签的下标
print(m_index4.labels[0])
print(m_index4.labels[1])
代码结果
FrozenNDArray([0, 0, 1, 1, 1], dtype='int8')
FrozenNDArray([0, 1, 2, 3, 4], dtype='int8')
个人博客https://syjun.vip
世界因代码而改变 Peace Out