Pandas基础(全)
引言
Pandas是基于Numpy的库,但功能更加强大,Numpy专注于数值型数据的操作,而Pandas对数值型,字符串型等多种格式的表格数据都有很好的支持。
关于Numpy的基础知识,请查看 Numpy基础(全)
内容介绍
1.数据结构(Series,DataFrame)
2.索引对象
3.索引操作
4.数据运算
5.层次化索引
6.可视化(暂时忽略)
一,数据结构
Pandas 采用了很多Numpy的代码风格,但Pandas是用来处理表格型或异质性数据的,而Numpy更适合处理同质型的数值类数组数据。
Pandas数据结构:Series 和 DataFrame
<1> Series
# Series 是一种一维的数组型对象,它包含了一个值序列(与 Numpy 中的类型相似),并且包含了数据标签,称为索引。
# 事实上纯数值型的Series对象的values属性就是一个Numpy数组。
# 最简单的序列可以仅仅由一个数组构成:
import pandas as pd
import numpy as np
obj = pd.Series([4,7,-5,3])
obj
# print(obj) # 打印效果和直接输出obj 效果一样
0 4
1 7
2 -5
3 3
dtype: int64
# 在交互式环境中,Series 的字符串表示为:索引在左边,值在右边。
# 1, 默认索引从0开始,可以通过 index属性 和 values属性分别获得Series对象的索引和值:
obj = pd.Series([4,7,-5,3])
obj.index # 与range(4)类似
RangeIndex(start=0, stop=4, step=1)
obj.values
array([ 4, 7, -5, 3], dtype=int64)
# 2, 可以自定义索引来替换默认索引:
obj2=pd.Series([4,7,-5,3],index=['d','b','a','c'])
# obj2.values
# obj2.index
obj2['a']
-5
# 可以使用 Series_obj.index属性,按位置赋值来改变索引:
obj2.index=['m','b','f','d']
obj2
m 4
b 7
f -5
d 3
dtype: int64
# 3, 对Series对象使用 Numpy 函数或 Numpy 风格的各种操作(如根据布尔型数组进行过滤,与标量相乘,或者应用数学函数),
# 都会保留索引与值之间的连接关系。
obj2[obj2>0] #以布尔型数组进行索引
d 4
b 7
c 3
dtype: int64
obj2*2
d 8
b 14
a -10
c 6
dtype: int64
np.exp(obj2) # 计算各元素的以e为底的指数
d 54.598150
b 1096.633158
a 0.006738
c 20.085537
dtype: float64
# 4, 也可以把 Series 看作是一种长度固定且有序的字典,因此在可能会使用字典的上下文中,使用Series来代替字典也是一个好主意。
print('Yes') if 'b' in obj2 else print('No')
print('Yes') if 'e' in obj2 else print('No')
Yes
No
# 5, 如果你已经将数据存放在了Python的字典中,你也可以使用字典来生成一个Series对象:
sdata={'Ohio':35000,'texas':71000,'Oregon':16000,'Utah':1000}
obj3=pd.Series(sdata) # 产生一个按【键】排好序的字典。
obj3
Ohio 35000
texas 71000
Oregon 16000
Utah 1000
dtype: int64
# 当然,也可以对键重新定义,当新定义的键在原字典中不存在时,Series处理这个缺失值为NaN。
# 当原来的字典中的键不存在于新定义的索引列表中时,这个键值对就会被排除掉。
obj4=pd.Series(sdata,index=["Tom",'Ohio','Ivan','Utah'])
obj4
Tom NaN
Ohio 35000.0
Ivan NaN
Utah 1000.0
dtype: float64
# 6, 检验缺失数据:
# pd.isnull(Series_obj) pd.notnull(Series_obj) 等同于 Series_obj.isnull() Series_obj.notnull() 返回布尔类型 Series对象:
# 既可以作为pandas的顶层函数,也可以作为 Series实例对象调用的方法。
# 在后面的章节中会深入的讨论如何处理缺失数据。
# pd.isnull(obj4)
obj4.isnull()
Tom True
Ohio False
Ivan True
Utah False
dtype: bool
# pd.notnull(obj4)
pd.notnull(obj4)
Tom False
Ohio True
Ivan False
Utah True
dtype: bool
# 7, Series的索引自动对齐:
# 因为上面的obj3和obj4有部分索引是一样的,所以我们对这两个Series对象进行操作:
# Series的索引自动对齐功能和数据库的join操作是很相似的。
obj3+obj4
Ivan NaN
Ohio 70000.0
Oregon NaN
Tom NaN
Utah 2000.0
texas NaN
dtype: float64
# 8, Series_obj.name 属性和 Series_obj.index.name 属性:
# 可以修改这两个属性(默认为None),他们往往和pandas的其他重要功能集成在一起。
print(obj4.name)
print(obj4.index.name)
obj4.name="population" # 人口
obj4.index.name="state" # 州
obj4
None
None
state
Tom NaN
Ohio 35000.0
Ivan NaN
Utah 1000.0
Name: population, dtype: float64
# 9, 按索引改变 Series对象的元素值:
# obj = pd.Series([4,7,-5,3],index=['Bob','Steve','Jeff','Ryan'])
obj = pd.Series([4,7,-5,3])
obj.index=['Bob1','Steve1','Jeff1','Ryan1']
obj['Steve1']=10
obj
Bob1 4
Steve1 10
Jeff1 -5
Ryan1 3
dtype: int64
<2> DataFrame
# DataFrame表示矩阵数据表,包含已经排序的列集合,每一列可以是不同的值类型(数值,字符串,布尔值等)。
# 既有行索引,也有列索引。
# 可以被视为共享相同索引的 Series的字典。
# 数据被存储为一个以上的二维块,而不是列表,字典或其他一维数组的集合。
# Note: 尽管 DataFrame是二维的,但可以利用分层索引在DataFrame中展现更高维度的数据。分层索引是pandas中一种更为高级的数据处理特性。
# DataFrame 既可以创建而来,也可以由其他数据类型转化而来。
# 1,创建 DataFrame
# 1)创建 DataFrame:
# 给 pd.DataFrame()传入由长度相等的列表,数组或元组组成的字典,创建DataFrame 对象.
# 字典的键位 DataFrame的列索引。
# DataFrame 构造函数的有效输入:
# 二维数组 2d ndarray 数据矩阵,行列的索引标签是可选参数 1-10)
# 数组,列表,元组,序列构成的字典 每个序列成为 DataFrame 的一列,所有的序列必须长度相等 1-1)至 1-5)
# Numpy 结构化/记录化数组 与数组构成的字典一致
# Series 构成的字典 每个 Series为一列,Series的索引合并为行索引,也可以显式的传递索引 1-1)至 1-4)
# 字典构成的字典(嵌套字典) 每一个内部字典形成一列,键联合起来形成结果的行索引 1-6)
# 字典或Series构成的列表 列表中的一个元素形成 DataFrame的一行,字典的键 或Series索引联合起来形成 DataFrame的列标签 1-8)1-9)
# 列表或元组构成的列表 与 2d ndarray的情况一致 1-7)
# 其他DataFrame 如果不显式传递索引,则会使用原 DataFrame 的索引
# Numpy MaskedArray 与 2d ndarray的情况类似,但隐藏值会在结果DataFrame 中成为 NA/缺失值
# 1-1) pd.DataFrame(dict_ndarrayvalu)
from pandas import Series,DataFrame
import pandas as pd
import numpy as np
data={
'name':np.array(['张三','李四','王五','小明']),
'sex':np.array(['female','female','male','male']),
'year':np.array([2001,2001,2003,2002]),
'city':np.array(['北京','上海','广州','深圳'])
}
df=DataFrame(data)
df
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
# 1-2)pd.DataFrame(dict_listvalue)
data1={
'name':['张三','李四','王五','小明'],
'sex':['female','female','male','male'],
'year':[2001,2001,2003,2002],
'city':['北京','上海','广州','深圳']
}
df1=DataFrame(data1)
df1
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
# 1-3)pd.DataFrame(dict_tuplevalue)
data1={
'name':('张三','李四','王五','小明'),
'sex':('female','female','male','male'),
'year':(2001,2001,2003,2002),
'city':('北京','上海','广州','深圳')
}
df1=DataFrame(data1)
df1
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
# 1-4)pd.DataFrame(dict_Seriesvalue)
data2={
'name':pd.Series(['张三','李四','王五','小明']),
'sex':pd.Series(['female','female','male','male']),
'year':pd.Series([2001,2001,2003,2002]),
'city':pd.Series(['北京','上海','广州','深圳'])
}
df02=DataFrame(data2)
df02
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
# 1-5)pd.DataFrame(dict_mixvalu)
data3={
'name':np.array(['张三','李四','王五','小明']),
'sex':('female','female','male','male'),
'year':[2001,2001,2003,2002],
'city':pd.Series(['北京','上海','广州','深圳'])
}
df03=DataFrame(data3)
df03
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
# 1-6) 使用嵌套字典的数据也可以创建 DataFrame 数据: 外层字典的键为列索引,内层字典的键为行索引
data2={
'sex':{'张三':'female','李四':'female','王五':'male'},
'city':{'张三':'北京','李四':'上海','王五':'广州'}
}
# df02=DataFrame(data2,index=['老大','李四','王五']) # 也可以这样显式地指定行/列索引的顺序或改变行/列数据。
df02=DataFrame(data2,index=['老大','李四','王五'],columns=['sex','city','newcolumn'])
df02
|
sex |
city |
newcolumn |
老大 |
NaN |
NaN |
NaN |
李四 |
female |
上海 |
NaN |
王五 |
male |
广州 |
NaN |
# 1-7) 使用列表或元组构成的嵌套列表创建 DataFrame 数据 ,每个内层列表/元组就是一行数据 行,列索引由 DataFrame()提供
# data = [['Alex',10],['Bob',12],['Clarke',13]]
import pandas as pd
data = [('Alex',10),('Bob',12),('Clarke',13)]
df = pd.DataFrame(data,columns=['Name','Age'],dtype=float)
df
|
Name |
Age |
0 |
Alex |
10.0 |
1 |
Bob |
12.0 |
2 |
Clarke |
13.0 |
# 1-8) 使用字典列表创建 DataFrame 数据 ,每个字典都包含了列标签(键)的一行数据(值)
data = [{'name':'Alex','age':10},{'name':'Bob','age':12},{'name':'Clarke','age':13}]
df = pd.DataFrame(data,dtype=float)
df
|
name |
age |
0 |
Alex |
10.0 |
1 |
Bob |
12.0 |
2 |
Clarke |
13.0 |
# 1-9) 使用Series对象创建 DataFrame 数据,每个Series都包含了列标签(index)的一行数据(值)
data = [pd.Series(['Alex',10],index=['Name','Age']),pd.Series(['Bob',12],index=['Name','Age']),pd.Series(['Clarke',13],index=['Name','Age'])]
df = pd.DataFrame(data,dtype=float)
df
|
Name |
Age |
0 |
Alex |
10.0 |
1 |
Bob |
12.0 |
2 |
Clarke |
13.0 |
# 1-10) 使用 2dndarray 创建 DataFrame 数据:
arr2d=np.array([['Alex',10],['Bob',12],['Clarke',13]])
df = pd.DataFrame(arr2d,columns=['name','age']) # 使用 2dndarray 创建 DataFrame 数据,不能指定 dtype=float,会报错
df
|
name |
age |
0 |
Alex |
10 |
1 |
Bob |
12 |
2 |
Clarke |
13 |
# 2,可以通过 columns和 index 属性来查看列和行:
df02.columns
Index(['sex', 'city'], dtype='object')
df02.index
Index(['老大', '李四', '王五'], dtype='object')
# 3,DataFrame的指定列索引列表,对列索引进行排序:
# 虽然上面的df都是按创建时的code 顺序对列进行排列的,但由于字典是无序的,所以为了安全起见,我们创建DataFrame时手动指定修改 列的顺序:
from pandas import DataFrame
import numpy as np
data={
'name':np.array(['张三','李四','王五','小明']),
'sex':np.array(['female','female','male','male']),
'year':np.array([2001,2001,2003,2002]),
'city':np.array(['北京','上海','广州','深圳'])
}
df02=DataFrame(data,columns=['name','year','sex','city']) # 语法
df02
|
name |
year |
sex |
city |
0 |
张三 |
2001 |
female |
北京 |
1 |
李四 |
2001 |
female |
上海 |
2 |
王五 |
2003 |
male |
广州 |
3 |
小明 |
2002 |
male |
深圳 |
# 4,指定行索引列表(没有指定行索引的情况下,默认的行索引是从0到N-1(N为数据长度))
df03=DataFrame(data,columns=['name','year','sex','city'],index=['a','b','c','d']) # 语法
df03
|
name |
year |
sex |
city |
a |
张三 |
2001 |
female |
北京 |
b |
李四 |
2001 |
female |
上海 |
c |
王五 |
2003 |
male |
广州 |
d |
小明 |
2002 |
male |
深圳 |
# 当指定的【列】索引在传入的data字典中不存在时,将会以缺失值NaN处理:
# 如果少指定了某列,生成的DataFrame对象就不含此列数据。
# 注意,如果多指定了行或少指定了行,就会报错。
df03=DataFrame(data,columns=['name','year','sex','city','job'],index=['a','b','c','d']) # 语法
df03
|
name |
year |
sex |
city |
job |
a |
张三 |
2001 |
female |
北京 |
NaN |
b |
李四 |
2001 |
female |
上海 |
NaN |
c |
王五 |
2003 |
male |
广州 |
NaN |
d |
小明 |
2002 |
male |
深圳 |
NaN |
# 5,对 DataFrame的行和列进行索引:
# 5-1)索引 DataFrame 的列返回 Series对象:
# Dataframe_obj[column] 或 Dataframe_obj.column 返回的结果为 Series 对象
# 返回的 Series对象与 DataFrame对象有相同的索引,且 Series的name 属性也会被合理的设置:
df04=DataFrame(data,columns=['name','year','sex','city','job'],index=['张','李','王','马'])
df04['sex']
张 female
李 female
王 male
马 male
Name: sex, dtype: object
sex=df04.sex
sex
张 female
李 female
王 male
马 male
Name: sex, dtype: object
# 5-2) 索引 DataFrame 的行返回 Series对象:
# 注意语法: dataframe_obj.loc[line_index] # DataFrame对象的特殊属性 loc
df04.loc['李']
name 李四
year 2001
sex female
city 上海
job NaN
Name: 李, dtype: object
# 5-3)通过列索引修改/赋值/创建 此列元素:
df04['job']='Data Analysis' # 将一个值赋值给一列
df04
|
name |
year |
sex |
city |
job |
张 |
张三 |
2001 |
female |
北京 |
Data Analysis |
李 |
李四 |
2001 |
female |
上海 |
Data Analysis |
王 |
王五 |
2003 |
male |
广州 |
Data Analysis |
马 |
小明 |
2002 |
male |
深圳 |
Data Analysis |
df04['job']=np.arange(4.) # 将一个与列等长度的ndarray数组赋值给一列
df04
|
name |
year |
sex |
city |
job |
张 |
张三 |
2001 |
female |
北京 |
0.0 |
李 |
李四 |
2001 |
female |
上海 |
1.0 |
王 |
王五 |
2003 |
male |
广州 |
2.0 |
马 |
小明 |
2002 |
male |
深圳 |
3.0 |
df04['job']=['Data Analysis']*4 # 将一个与列等长度的列表赋值给一列
df04
|
name |
year |
sex |
city |
job |
张 |
张三 |
2001 |
female |
北京 |
Data Analysis |
李 |
李四 |
2001 |
female |
上海 |
Data Analysis |
王 |
王五 |
2003 |
male |
广州 |
Data Analysis |
马 |
小明 |
2002 |
male |
深圳 |
Data Analysis |
val=pd.Series(['Data Analysis dev','Data Analysis im','Data Analysis ba'],index=['马','李','张'])
df04['job']=val # 将一个长度<=列长度的 Series对象赋值给一列, 缺失值处理为NAN,按照 DataFrame的索引排列
df04
|
name |
year |
sex |
city |
job |
张 |
张三 |
2001 |
female |
北京 |
Data Analysis ba |
李 |
李四 |
2001 |
female |
上海 |
Data Analysis im |
王 |
王五 |
2003 |
male |
广州 |
NaN |
马 |
小明 |
2002 |
male |
深圳 |
Data Analysis dev |
val=pd.Series(['band 6A','band 8B','band 7B'],index=['马','李','王'])
df04['band']=val # 如果列索引并不存在,创建一个新的列。(无论赋值的内容是列表,Series或值)
df04
# 说明了 从 DataFrame里选取的列是数据的视图,不是拷贝。对 Series的修改会映射到 DataFrame里。
|
name |
year |
sex |
city |
job |
band |
张 |
张三 |
2001 |
female |
北京 |
Data Analysis ba |
NaN |
李 |
李四 |
2001 |
female |
上海 |
Data Analysis im |
band 8B |
王 |
王五 |
2003 |
male |
广州 |
NaN |
band 7B |
马 |
小明 |
2002 |
male |
深圳 |
Data Analysis dev |
band 6A |
# 6,del 关键字 删除DataFrame的列
# 像字典中删除键一样
data={
'name':np.array(['张三','李四','王五','小明']),
'sex':np.array(['female','female','male','male']),
'year':np.array([2001,2001,2003,2002]),
'city':np.array(['北京','上海','广州','深圳'])
}
df04=DataFrame(data)
# step1 先增加一列,再删掉:
df04['new']=df04.sex=='female' # Note:df04.new 的语法 无法用来创建新的列,也无法用来删除指定的列
df04
|
name |
sex |
year |
city |
new |
0 |
张三 |
female |
2001 |
北京 |
True |
1 |
李四 |
female |
2001 |
上海 |
True |
2 |
王五 |
male |
2003 |
广州 |
False |
3 |
小明 |
male |
2002 |
深圳 |
False |
del df04['new']
df04.columns
Index(['name', 'sex', 'year', 'city'], dtype='object')
# 7,DataFrame数据的复制:
# 要显式地使用Series的copy方法:
series_copy=df04['sex'].copy()
series_copy
0 female
1 female
2 male
3 male
Name: sex, dtype: object
series_copy[2]='female' # 注意是 series_copy[2] 而不是 series_copy['2'],如果用后者,相当于创建一个新的元素。
series_copy
0 female
1 female
2 female
3 male
Name: sex, dtype: object
df04 # 对 series_copy 的修改不会影响原来的 dataframe
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
# 8,DataFrame 的转置
# 语法: 类似 Numpy, dataframe_obj.T
df04.T
|
0 |
1 |
2 |
3 |
name |
张三 |
李四 |
王五 |
小明 |
sex |
female |
female |
male |
male |
year |
2001 |
2001 |
2003 |
2002 |
city |
北京 |
上海 |
广州 |
深圳 |
df04
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
# 9,给列索引和行索引的 name 属性赋值:
df04.index.name='Name'
df04.columns.name='Infor'
df04
Infor |
name |
sex |
year |
city |
Name |
|
|
|
|
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
# 10,DataFrame的 index, column, values属性
df04.index # 一维数组
RangeIndex(start=0, stop=4, step=1, name='Name')
df04.columns # 一维数组
Index(['name', 'sex', 'year', 'city'], dtype='object', name='Infor')
df04.values # 二维数组
array([['张三', 'female', 2001, '北京'],
['李四', 'female', 2001, '上海'],
['王五', 'male', 2003, '广州'],
['小明', 'male', 2002, '深圳']], dtype=object)
# df04['new']=['12','abc',12,'NaN']
df04['new']=pd.Series(['Data Analysis dev','Data Analysis im','Data Analysis ba'],index=[0,1,2])
df04.values
array([['张三', 'female', 2001, '北京', 'Data Analysis dev'],
['李四', 'female', 2001, '上海', 'Data Analysis im'],
['王五', 'male', 2003, '广州', 'Data Analysis ba'],
['小明', 'male', 2002, '深圳', nan]], dtype=object)
二,索引对象
#以下按照《零基础 Python数据分析》来学习。
# DataFrame的索引也是对象,这些对象有自己的方法和属性
# pandas 中的索引对象是用于存储轴标签和其他元数据的 (例如轴名称或标签)。
# Series 或 DataFrame 时,你所使用任意数组或标签序列都可以在内部转换为索引对象。
data={
'name':np.array(['张三','李四','王五','小明']),
'sex':('female','female','male','male'),
'year':[2001,2001,2003,2002],
'city':('北京','上海','广州','深圳')
}
df=DataFrame(data)
# 1,索引对象
df.index
RangeIndex(start=0, stop=4, step=1)
df.columns
Index(['name', 'sex', 'year', 'city'], dtype='object')
# 2, 索引对象不可更改,强改会报错:
# index=df.index
col = df.columns
# index[1]=0
col[1]='a'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-144-daed13b54382> in <module>
3 col = df.columns
4 # index[1]=0
----> 5 col[1]='a'
~anaconda3envsdata_analysislibsite-packagespandascoreindexesase.py in __setitem__(self, key, value)
3908
3909 def __setitem__(self, key, value):
-> 3910 raise TypeError("Index does not support mutable operations")
3911
3912 def __getitem__(self, key):
TypeError: Index does not support mutable operations
# 3,索引对象类似于数组,其功能类似于一个固定大小的集合
df.index.name='infor item'
df.columns.name='details'
df
details |
name |
sex |
year |
city |
infor item |
|
|
|
|
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
'sex' in df.columns
True
2 in df.index
True
三,索引操作
# (1)讲解 Series 和 DataFrame 的索引操作的方法
# (2)与 Excel 数据类比,讲解 DataFrame 数据的选取与操作
# 1,重新索引:
# 1-1)Series 重新索引: s_obj.reindex(新索引列表[,method='ffill']) 返回一个新的 Series对象,不改变原来的 Series.
# 其中 method 参数可以缺省,缺省时,新索引列表中新引入的索引对应的元素值为 NaN,
# method='ffill'或'pad' 指元素值与前后一行相同(向前填充),method='bfill' 或'pad' 指元素值与前一行相同(向后填充)。
s_obj=Series([1,2,3,4],index=['a','c','d','f'])
s_obj
a 1
c 2
d 3
f 4
dtype: int64
s_obj2=s_obj.reindex(['a','c','m','d','e']) # 没有使用原来的索引 c,新引入了索引 e
s_obj2
a 1.0
c 2.0
m NaN
d 3.0
e NaN
dtype: float64
# reindex重新索引后,引入原 Series没有的索引时,可用 method='ffill',method='bfill' 进行填充。
# 填充规则:新引入的索引与原索引进行字符排序,按字符顺序的先后 进行向前或向后填充。
s_obj3=s_obj.reindex(['a','b','m','d','e'],method='ffill') # 向后填充, 用a对应的值向后填充b,用 f对应的值向后填充 m
s_obj3
a 1
b 1
m 4
d 3
e 3
dtype: int64
s_obj4=s_obj.reindex(['a','b','m','d','e'],method='bfill') # 向前填充。 用 c对应的值向前填充 b, m之后的值(NaN)向前填充m
s_obj4
f 4.0
b 2.0
m NaN
d 3.0
e 4.0
dtype: float64
s_obj # 不改变原来的 Series对象
a 1
b 2
c 3
d 4
dtype: int64
# 1-2)DataFrame 的重新索引:
# 对于 DataFrame 数据来说,行和列索引都可以被重新索引:
import numpy as np
import pandas as pd
from pandas import DataFrame,Series
df=DataFrame(np.arange(9).reshape((3,3)),index=['a','c','d'],columns=['name','id','sex'])
df
|
name |
id |
sex |
a |
0 |
1 |
2 |
c |
3 |
4 |
5 |
d |
6 |
7 |
8 |
# 重新索引行:
df2=df.reindex(['a','b','c','d'])
# df2=df.reindex(index=['a','n','c','d']) # 重新指定行索引时 index关键字 可以省略
df2
|
name |
id |
sex |
a |
0.0 |
1.0 |
2.0 |
b |
NaN |
NaN |
NaN |
c |
3.0 |
4.0 |
5.0 |
d |
6.0 |
7.0 |
8.0 |
# 重新索引列:
gender=df2.sex
df3=df.reindex(columns=['name','id','gender','job'],fill_value=[0,1,2]) # 重新指定列索引要使用 columns关键字
df3['gender']=gender
df3
|
name |
id |
gender |
job |
a |
0 |
1 |
2.0 |
[0, 1, 2] |
c |
3 |
4 |
5.0 |
[0, 1, 2] |
d |
6 |
7 |
8.0 |
[0, 1, 2] |
# 总结 reindex 函数的参数使用说明:
index 用于索引的新序列
method 填充缺失值方法 method='bfill' method='ffill'
fill_value 缺失值替代值 fill_value 将接收到的值assign给每一个缺失的元素,并不解包。
limit 最大填充量 (遇到再看)
# 2,更换索引:(针对 DataFrame) 返回新的 DataFrame, 不改变原来的 DataFrame
# set_index('某个列索引') # 使用某一列作为行索引,通常用来替代默认的行索引
import numpy as np
import pandas as pd
from pandas import DataFrame,Series
data={
'name':np.array(['张三','李四','王五','小明']),
'sex':('female','female','male','male'),
'year':[2001,2001,2003,2002],
'city':pd.Series(['北京','上海','广州','深圳'])
}
df=DataFrame(data)
df
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
df2=df.set_index('name') # 使用 name 这列来替代默认行索引,'name'变成了行索引的index.name 属性值。
print(df2.index.name,df2.columns.name)
df2
# df3=df2.set_index('sex') 此时会将 将sex这列作为新返回的 d3的行索引,name列不存在于df3中。
name None
|
sex |
year |
city |
name |
|
|
|
张三 |
female |
2001 |
北京 |
李四 |
female |
2001 |
上海 |
王五 |
male |
2003 |
广州 |
小明 |
male |
2002 |
深圳 |
df3=df2.reset_index()
print(df3.index.name,df3.columns.name)
df3
None None
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2001 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
# 对 DataFrame行索引的排序,行索引会随之排序,但excel表格里不会.
data={
'name':np.array(['张三','李四','王五','小明']),
'sex':('female','female','male','male'),
'year':[2001,2000,2003,2002],
'city':pd.Series(['北京','上海','广州','深圳'])
}
df=DataFrame(data)
df2=df.sort_values(by='year') # 不改变原 DataFrame,返回新的 DataFrame
df2
|
name |
sex |
year |
city |
1 |
李四 |
female |
2000 |
上海 |
0 |
张三 |
female |
2001 |
北京 |
3 |
小明 |
male |
2002 |
深圳 |
2 |
王五 |
male |
2003 |
广州 |
# 此时,如果我们想得到像excel那样,数据排序之后,行号不跟随排序,依然是0,1,2...,可以:
df3=df2.reset_index() #将默认行索引变为 列, 重新生成一个新的默认行号:
df3
|
index |
name |
sex |
year |
city |
0 |
1 |
李四 |
female |
2000 |
上海 |
1 |
0 |
张三 |
female |
2001 |
北京 |
2 |
3 |
小明 |
male |
2002 |
深圳 |
3 |
2 |
王五 |
male |
2003 |
广州 |
df4=df2.reset_index(drop=True) # 这样既可以生成一个新的默认行索引,又会删除多余的行索引。
df4
|
name |
sex |
year |
city |
0 |
李四 |
female |
2000 |
上海 |
1 |
张三 |
female |
2001 |
北京 |
2 |
小明 |
male |
2002 |
深圳 |
3 |
王五 |
male |
2003 |
广州 |
# 3,索引和选取
# 通过索引来选取数据是 Series和 DataFrame 选取数据的手段(excel可以鼠标选取,VBA可以code指定)
# 3-1)Series 的数据选取:
# 3-1-1) Series_obj[n] # n是 0 到 Series_obj.size-1 范围的数。
# 3-1-2) Series_obj(行索引标签)
# 对选取元素的值的更改,会影响到原来的 Series或 DataFrame。
from pandas import Series,DataFrame
Series_obj=Series([1,2,1,5],index=['i1','i2','i3','i4'])
print(Series_obj[2])
print(Series_obj['i3']) # 单元素索引返回单个值
Series_obj[['i1','i4']] # 多元素索引 返回序列
Series_obj[:'i1'] # 切片索引 注意,与 Python列表不同之处: 列表是含左不含右, Series是都包含。 返回序列
Series_obj[:'i3'] # 切片索引 注意,与 Python列表不同之处: 列表是含左不含右, Series是都包含。 返回序列
Series_obj[Series_obj==2] # 布尔索引 无论符合条件的结果是单个元素还是多个元素,返回的都是序列
Series_obj[Series_obj<2] # 布尔索引 无论符合条件的结果是单个元素还是多个元素,返回的都是序列
Series_obj[2]=6 # 对选取元素的值的更改,会影响到原来的 Series或 DataFrame
Series_obj
1
1
i1 1
i2 2
i3 6
i4 5
dtype: int64
# 3-2)DataFrame 的数据选取:
# 选取行,选取列,选取行列子集
data={
'name':np.array(['张三','李四','王五','小明']),
'sex':('female','female','male','male'),
'year':[2001,2000,2003,2002],
'city':pd.Series(['北京','上海','广州','深圳'])
}
df=DataFrame(data)
df
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2000 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
df2=df.set_index('name')
df2
|
sex |
year |
city |
name |
|
|
|
张三 |
female |
2001 |
北京 |
李四 |
female |
2000 |
上海 |
王五 |
male |
2003 |
广州 |
小明 |
male |
2002 |
深圳 |
# df2['王五'] # 报错
# df2[1] # 报错
# df.loc[df.index[0,2], ['name','city']] #报错
# df.loc[df.index[[0,2]], df.columns['name','city']] #报错
# df.loc[df.index[0:2], ['name','city']] #可以
# df.loc[df.index[[0,2]], ['name','city']] #可以
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-155-c741d5a2df48> in <module>
5 # df.loc[df.index[0:2], ['name','city']] #可以
6 # df.loc[df.index[[0,2]], ['name','city']] #可以
----> 7 df.loc[df.index[[0,2]], df.columns['name','city']] #可以
~anaconda3envsdata_analysislibsite-packagespandascoreindexesase.py in __getitem__(self, key)
3939
3940 key = com.values_from_object(key)
-> 3941 result = getitem(key)
3942 if not is_scalar(result):
3943 if np.ndim(result) > 1:
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices
# DataFrame 行列 选取总结:
# df2['王五'] # 报错
# df2[1] # 报错
# 多行:
# df2.[['张三','王五']] # 报错
# df2.[[1,3]] # 报错
# 为了防止弄混,DataFrame选取多行时,一律使用 loc和 iloc:(当使用切片时,不使用 loc iloc也是允许的)
# 单行:
df.loc['王五']
df.iloc[1]
# 多行:
df.iloc[0:2]
df.loc['李四':'王五']
df.loc[['张三','王五']]
df.iloc[[1,3]]
# 单列:
df.year # 按属性选取
df['year'] # 按列索引标签选取
# 多列:(不可使用切片)
df[['year','name']]
# 选取行列子集:
df.loc[df.index[0:2], ['name','city']]
df.loc[df.index[[0,2]], ['name','city']]
df.iloc[df.index[[0,2]], [0,2]]
# 布尔选择
# 与数组布尔型索引相似:!= ~ & |
df['sex']=='female' # 对某一列进行条件判断,返回布尔型 Series
df[df['sex']=='female'] # 返回符合条件的行列子集
df[df['sex']=='female' & df['year']==2001] # 必须使用括号
df[(df['sex']=='female') & ~(df['year']==2001)]
df[(df['sex']=='female') & (df['year']!=2001)]
df[(df['sex']=='female') | (df['year']==2002)]
# 对索引出来的数据进行修改,会影响到原来的数据结构
df[df['sex']=='female'] ='haha'
df['year'] = 2010
# 要想索引出来的数据独立使用,不影响原来数据结构,就要使用 .copy()
df2=df[df['sex']=='female'].copy()
df2.year=2030
df2=df[df['sex']=='female'].copy()
df2.year=2030
df2
# df
# df['year'] = 2010
# df
|
name |
sex |
year |
city |
0 |
张三 |
female |
2030 |
北京 |
1 |
李四 |
female |
2030 |
上海 |
# 4,DataFrame的增,删,改,查(即索引)-----操作行和列
# 不会改变原来的 DataFrame,返回一个新的 DataFrame
# 4-1)查 上面的3-2)已经涵盖
# 4-2)增
# 4-2-1)对行的增加: df.append(new_data,ignore_index=True) 增加一行数据
import numpy as np
from pandas import DataFrame,Series
import pandas as pd
data={
'name':np.array(['张三','李四','王五','小明']),
'sex':('female','female','male','male'),
'year':[2001,2000,2003,2002],
'city':pd.Series(['北京','上海','广州','深圳'])
}
df=DataFrame(data)
new_data={
'name':"Tom",
'sex':'male',
'year':2007,
'city':'南京'
}
df2=df.append(new_data,ignore_index=True) # 返回一个新的 DataFrame, 不影响原来的。
df2
# df
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2000 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
4 |
Tom |
male |
2007 |
南京 |
# 4-2-2)对列的增加删除和修改在 《一,创建 DataFrame 4-3)通过列索引修改/赋值/创建 此列元素》 一节
# 4-3)删
# 4-3-1) 删除行:new_df=df.drop(2) 针对行索引是数字的有效。 不指定axis时,默认axis=0
new_df=df2.drop(4)
new_df
|
name |
sex |
year |
city |
0 |
张三 |
female |
2001 |
北京 |
1 |
李四 |
female |
2000 |
上海 |
2 |
王五 |
male |
2003 |
广州 |
3 |
小明 |
male |
2002 |
深圳 |
new_df2=new_df.set_index('name')
new_df2
|
sex |
year |
city |
name |
|
|
|
张三 |
female |
2001 |
北京 |
李四 |
female |
2000 |
上海 |
王五 |
male |
2003 |
广州 |
小明 |
male |
2002 |
深圳 |
# new_df3=new_df2.drop(1) # 报错, 当行索引变为name时,数字参数不好用。
new_df3=new_df2.drop('李四',axis=0) # 不指定 axis时,默认axis=0 new_df2.drop('李四')
new_df3
|
sex |
year |
city |
name |
|
|
|
张三 |
female |
2001 |
北京 |
王五 |
male |
2003 |
广州 |
小明 |
male |
2002 |
深圳 |
# 4-3-2) 删除列:new_df=df.drop('city',axis=1)
# 或
# del df['city'](会影响原数据)
new_df4=new_df3.drop('city',axis=1)
new_df4
# new_df3
|
sex |
year |
city |
name |
|
|
|
张三 |
female |
2001 |
北京 |
王五 |
male |
2003 |
广州 |
小明 |
male |
2002 |
深圳 |
del new_df3['city'] # 会影响原数据
new_df3
|
sex |
year |
name |
|
|
张三 |
female |
2001 |
王五 |
male |
2003 |
小明 |
male |
2002 |
# 4-4)改 当参数inplace=True时,会原地修改,当inplace=False或缺省时,不会影响原数据,返回一个新的数据。
# 这里的修改是指 对行列索引标签的修改,通过 df.rename()函数,可完成由于某些原因导致的标签录入错误的问题:
# new_df4=new_df3.rename(index={'王五':'王老五','小明':'马六'},columns={'sex':'gender'})
# new_df4
new_df3.rename(index={'王五':'王老五','小明':'马六'},columns={'sex':'gender'},inplace=True) # 可在原数据上进行修改
new_df3
|
gender |
year |
name |
|
|
张三 |
female |
2001 |
王老五 |
male |
2003 |
马六 |
male |
2002 |
四,数据运算(重点内容)
# 1,pandas 算术运算
# 参与运算的 各个 Series 的size大小任意。
# 参与运算的 各个 DataFrame 的行数必须相同。
# 1-1)Series 算术运算
# 有共同索引的元素才会进行算术运算,如果没有,则引入 NaN --对齐操作
S1=Series([2.1,5,-3,0.2,0.3],index=['a','c','d','f','g'])
S2=Series([3.5,1.5,-2,0.5],index=['a','b','d','e']) # 共同索引为 'a','d'
S1+S2
a 5.6
b NaN
c NaN
d -5.0
e NaN
f NaN
g NaN
dtype: float64
# 1-2)DataFrame 算术运算
# 对于 DataFrame数据,对齐操作会同时发生在行和列上
df1=DataFrame(np.arange(9).reshape(3,3),index=['apple','banana','tea'],columns=['a','b','c'])
df2=DataFrame(np.arange(9).reshape(3,3),index=['apple','banana','coco'],columns=['a','b','d'])
df1+df2 # 运算返回的结果包含了参与运算的 df的所有的列,
|
a |
b |
c |
d |
apple |
0.0 |
2.0 |
NaN |
NaN |
banana |
6.0 |
8.0 |
NaN |
NaN |
coco |
NaN |
NaN |
NaN |
NaN |
tea |
NaN |
NaN |
NaN |
NaN |
# 1-3)DataFrame 和 Series的 算术运算:
# 要求 Series的【行索引】和 DataFrame的【列索引】要一致。
#
S1=Series([2,3,4],index=['a','b','c'])
df1=DataFrame(np.arange(9).reshape(3,3),index=['apple','banana','tea'],columns=['a','b','c'])
df1+S1 # df的 a列+2 b列+3,c列+4
|
a |
b |
c |
apple |
2 |
4 |
6 |
banana |
5 |
7 |
9 |
tea |
8 |
10 |
12 |
df1=DataFrame(np.arange(9).reshape(3,3),index=['apple','banana','tea'],columns=['a','b','c'])
s1=df1.loc['apple'] # 取 DtaFrame的单行,这样取得的 Series的索引为 DataFrame的列索引
s1
a 0
b 1
c 2
Name: apple, dtype: int32
df1+s1
|
a |
b |
c |
apple |
0 |
2 |
4 |
banana |
3 |
5 |
7 |
tea |
6 |
8 |
10 |
# 2, 函数应用与映射
# 自定义函数对数据进行较为复杂的函数运算,然后应用到 pandas数据中
# 有三种使用自定义函数的datafrom方法: 参数 f 为自定义函数,也可以是lambda表达式
# 6-1)se.map(f) 函数 将函数套用在每个 Series 元素上
# 6-2)df.aplly(f,axis=1)函数 将函数套用在 DataFrame的行与列上,若 axis缺省,则默认axis=0
# 6-3)df.applymap(f)函数 将函数套用在 DataFrame的每个元素上
# 2-1)df.map(f) 函数 用在 Series元素上
# 使用 map函数,去掉‘元’字
data={
'fruit':['apple','orange','grape','banana'],
'price':['25元','42元','35元','15元']
}
df1=DataFrame(data)
df1
|
fruit |
price |
0 |
apple |
25元 |
1 |
orange |
42元 |
2 |
grape |
35元 |
3 |
banana |
15元 |
def removeyuan(x):
return x.split('元')[0] # 取‘25元’中的‘25’
# df1['price']=df1['price'].map(removeyuan) # df1['price'] 是序列
# 可以使用 lambda表达式代替 f:
df1['price']=df1['price'].map(lambda x:x.split('元')[0]) # 放在map()里 x在这里代表 元素
df1
|
fruit |
price |
0 |
apple |
25 |
1 |
orange |
42 |
2 |
grape |
35 |
3 |
banana |
15 |
# 2-2)df.apply(f) 函数
df2=DataFrame(np.random.randn(3,3),columns=['a','b','c'],index=['linux','win','mac'])
df2
|
a |
b |
c |
linux |
2.289954 |
-0.86051 |
-0.419287 |
win |
0.079616 |
-2.25940 |
-1.128554 |
mac |
-0.828268 |
-0.35262 |
1.106663 |
f=lambda x:x.max()-x.min() # 放在apply()里 x在这里代表 行或列
df2.apply(f)
a 3.118222
b 1.906779
c 2.235217
dtype: float64
df2.apply(f,axis=1)
linux 3.150464
win 2.339016
mac 1.934931
dtype: float64
# 2-3)df.applymap(f) 函数
df2.applymap(lambda x:'%.2f'%x) # 保留小数点两位
|
a |
b |
c |
linux |
2.29 |
-0.86 |
-0.42 |
win |
0.08 |
-2.26 |
-1.13 |
mac |
-0.83 |
-0.35 |
1.11 |
# 3, 排序
# 排序不会影响原来的 数据,返回新的数据。
# 3-1)Series se.sort_index(ascending=False)
# 对索引进行排序 ascending缺省时默认升序,ascending=False为降序
s1=Series([1,-1,3,2],index=['b','a','d','c'])
s1
b 1
a -1
d 3
c 2
dtype: int64
s1.sort_index() # 升序
s1.sort_index(ascending=False) # 降序
# s1 # 不会影响原来数据
d 3
c 2
b 1
a -1
dtype: int64
# 3-2) Series se.sort_values(ascending=False)
# 对value进行排序 ascending缺省时默认升序,ascending=False为降序
s1=Series([2,-1,3,5],index=['b','a','d','c'])
s1.sort_values()
s1.sort_values(ascending=False)
c 5
d 3
b 2
a -1
dtype: int64
# 3-3) DataFrame df.sort_index(asix=1,ascending=False) 对指定轴的 索引 进行排序
# 当axis缺省时,默认为 axis=0, 当 ascending缺省时,默认ascending=True
df1=DataFrame(np.random.randn(3,3),columns=['a','d','c'],index=['linux','win','mac'])
df1
|
a |
d |
c |
linux |
0.282841 |
-1.783628 |
-0.685621 |
win |
-0.548632 |
0.754350 |
0.047237 |
mac |
-0.521260 |
-0.089012 |
-0.711214 |
df1.sort_index(axis=0,ascending=True)
# df1.sort_index(axis=1)
|
a |
d |
c |
linux |
0.282841 |
-1.783628 |
-0.685621 |
mac |
-0.521260 |
-0.089012 |
-0.711214 |
win |
-0.548632 |
0.754350 |
0.047237 |
# 3-4) DataFrame df.sort_values(by='d',ascending=False) 对指定列的值进行排序
# 当 ascending缺省时,默认ascending=True
df1.sort_values(by='d',ascending=False)
|
a |
d |
c |
win |
-0.548632 |
0.754350 |
0.047237 |
mac |
-0.521260 |
-0.089012 |
-0.711214 |
linux |
0.282841 |
-1.783628 |
-0.685621 |
# 4, 汇总与统计
# df.sum(axis=0)
# axis=0 或 axis缺省 表示对每一列分别求和,axis=1表示对行求和,返回 Series数据。
# df.describe() 对每个数值型【列】进行统计,用于对数据的初步观察时使用,得到一个关于最值,平均值,标准差等信息的 DataFrame.
df=DataFrame(np.random.randn(3,3),columns=['a','d','c'])
df
|
a |
d |
c |
0 |
0.871841 |
1.235904 |
0.173434 |
1 |
-2.764356 |
-0.641077 |
-0.107045 |
2 |
0.182462 |
0.602054 |
-1.230373 |
df.sum(axis=1)
df.sum()
a -1.710053
d 1.196880
c -1.163983
dtype: float64
df.describe()
|
a |
d |
c |
count |
3.000000 |
3.000000 |
3.000000 |
mean |
-0.570018 |
0.398960 |
-0.387994 |
std |
1.931360 |
0.954830 |
0.742878 |
min |
-2.764356 |
-0.641077 |
-1.230373 |
25% |
-1.290947 |
-0.019512 |
-0.668709 |
50% |
0.182462 |
0.602054 |
-0.107045 |
75% |
0.527151 |
0.918979 |
0.033195 |
max |
0.871841 |
1.235904 |
0.173434 |
# 5, 唯一值与值计数 重点内容
# 都是针对 Series 对象而言的 (DataFrame的行和列也是 Series)
# series.unique() 获取不重复元素组成的 ndarray数组
s1=Series([2,-1,3,2,1,4,5,3,5])
s1.unique()
array([ 2, -1, 3, 1, 4, 5], dtype=int64)
# series.value_counts() 可以统计每个值出现的次数 返回以序列元素为索引,以次数为元素的 Series.#
s1.value_counts()
5 2
3 2
2 2
4 1
1 1
-1 1
dtype: int64
# 对于 DataFrame的行和列
data={
'fruit':['apple','orange','apple','banana'],
'price':[25,42,25,15],
'name':['myapple','orange','apple','bolo']
}
df1=DataFrame(data)
df1
|
fruit |
price |
name |
0 |
apple |
25 |
myapple |
1 |
orange |
42 |
orange |
2 |
apple |
25 |
apple |
3 |
banana |
15 |
bolo |
df1['fruit'].unique()
array(['apple', 'orange', 'banana'], dtype=object)
df1['fruit'].value_counts()
apple 2
orange 1
banana 1
Name: fruit, dtype: int64
df1.iloc[2].unique()
array(['apple', 25], dtype=object)
df1.iloc[2].value_counts()
apple 2
25 1
Name: 2, dtype: int64
五,层次化索引
# 层次化索引就是轴上有多个级别索引,即索引是个多维列表,这里只讨论二维列表。
# 1,Series 数据的层次化索引创建:
series_obj=Series(np.random.randn(9),index=[['one','one','one','two','two','two','three','three','three'],['a','b','c']*3])
series_obj
one a -0.913606
b 1.258280
c 0.430108
two a 0.366005
b -1.821770
c 1.135238
three a 0.131614
b -0.407047
c 0.576246
dtype: float64
series_obj['two'] # 对层次化序列的外层索引
a 0.366005
b -1.821770
c 1.135238
dtype: float64
series_obj[:,'a'] # 对层次化序列的内层索引 所有行的 a 行
one -0.913606
two 0.366005
three 0.131614
dtype: float64
series_obj['two','a'] # 对层次化序列的内层索引 two行的 a 行
0.36600524764982423
series_obj.index # 该索引对象为 MulitiIndex
MultiIndex([( 'one', 'a'),
( 'one', 'b'),
( 'one', 'c'),
( 'two', 'a'),
( 'two', 'b'),
( 'two', 'c'),
('three', 'a'),
('three', 'b'),
('three', 'c')],
)
# 2,DataFrame 数据的层次化索引创建:
# 对于 DataFrame,行和列都可以为层次化索引:
df1=DataFrame(np.arange(16).reshape(4,4),index=[['one','one','two','two'],['a','b','a','b']])
df1
|
|
0 |
1 |
2 |
3 |
one |
a |
0 |
1 |
2 |
3 |
b |
4 |
5 |
6 |
7 |
two |
a |
8 |
9 |
10 |
11 |
b |
12 |
13 |
14 |
15 |
df2=DataFrame(np.arange(16).reshape(4,4),columns=[['one','one','two','two'],['a','b','a','b']])
df2
|
one |
two |
|
a |
b |
a |
b |
0 |
0 |
1 |
2 |
3 |
1 |
4 |
5 |
6 |
7 |
2 |
8 |
9 |
10 |
11 |
3 |
12 |
13 |
14 |
15 |
df3=DataFrame(np.arange(16).reshape(4,4),index=[['one','one','two','two'],['a','b','a','b']],
columns=[['apple','apple','orange','orange'],['size','price','size','price']])
df3
|
|
apple |
orange |
|
|
size |
price |
size |
price |
one |
a |
0 |
1 |
2 |
3 |
b |
4 |
5 |
6 |
7 |
two |
a |
8 |
9 |
10 |
11 |
b |
12 |
13 |
14 |
15 |
df3['apple']
|
|
size |
price |
one |
a |
0 |
1 |
b |
4 |
5 |
two |
a |
8 |
9 |
b |
12 |
13 |
df3['apple','size'] # 返回从层次化索引序列
one a 0
b 4
two a 8
b 12
Name: (apple, size), dtype: int32
df3.loc['one']
|
apple |
orange |
|
size |
price |
size |
price |
a |
0 |
1 |
2 |
3 |
b |
4 |
5 |
6 |
7 |
df3.loc['one','a'] # 返回层次化索引序列
apple size 0
price 1
orange size 2
price 3
Name: (one, a), dtype: int32
# 3,重排分级顺序
# 用到再细研究
# 通过 swaplevel 方法可以对层次化索引进行重排:
df3
|
|
apple |
orange |
|
|
size |
price |
size |
price |
one |
a |
0 |
1 |
2 |
3 |
b |
4 |
5 |
6 |
7 |
two |
a |
8 |
9 |
10 |
11 |
b |
12 |
13 |
14 |
15 |
df3.swaplevel(0,1)
|
|
apple |
orange |
|
|
size |
price |
size |
price |
a |
one |
0 |
1 |
2 |
3 |
b |
one |
4 |
5 |
6 |
7 |
a |
two |
8 |
9 |
10 |
11 |
b |
two |
12 |
13 |
14 |
15 |
# 4,对层次化索引的 pandas 数据进行汇总统计
# 对层次化索引的 pandas 数据进行汇总统计时,可以通过 level 参数指定在某层次上进行汇总统计。
# sum()的参数 level=0 表示按相同外层索引的所有子行或子列相加,level=1 表示按相同内层索引的行或列进行求和。
# 层次化索引的用途在后面会详细讲解。
df3.sum(level=0,axis=0) # 表示按相同外层索引的所有子行或子列相加 one 的 a+b two 的 a+b
|
apple |
orange |
|
size |
price |
size |
price |
one |
4 |
6 |
8 |
10 |
two |
20 |
22 |
24 |
26 |
df3.sum(level=1,axis=0) # 表示按相同内层索引的行或列进行求和 one和two的 a+a , b+b
|
apple |
orange |
|
size |
price |
size |
price |
a |
8 |
10 |
12 |
14 |
b |
16 |
18 |
20 |
22 |
df3.sum(level=0,axis=1) # 表示按相同外层索引的所有子行或子列相加
|
|
apple |
orange |
one |
a |
1 |
5 |
b |
9 |
13 |
two |
a |
17 |
21 |
b |
25 |
29 |
df3.sum(level=1,axis=1) # 表示按相同内层索引的行或列进行求和
|
|
size |
price |
one |
a |
2 |
4 |
b |
10 |
12 |
two |
a |
18 |
20 |
b |
26 |
28 |
六,可视化(暂时忽略)
下一篇将讲述 pandas对外部数据的读取,处理和存储。