========================
INTRODUCTION TO PANDAS
========================
圆括号是函数,方括号是索引
#Series data can be numpy array,or a python dict
#定义的方法:s = Series(data, index) #先指定数值再指定索引
无论选取何种方式都需要指定序列的长度,即元素的个数
s=Series(randn(5))
s = Series(randn(5), index=['a', 'b', 'c', 'd', 'e']) #索引的数量需要等于元素的数量,否则报错
d={'a':1,'b':2,'c':3}
s=Series(data=d,index=['b', 'c', 'd', 'a'])#显式地指定序列的索引值,输出的数据中,列已经排序。同时在数据中没有对应的键d则记为NULL
s=Series(5., index=['a', 'b', 'c', 'd', 'e'])#全部元素只有一个值
#序列元素的选取,索引始终保留
s[:3]
s[s > s.median()] #支持numpy的函数
s[s>3] #逻辑运算,取出大于3的元素
s[[1,2,4]] #由列表指定的元素
s[['a','b']] #由列表指定索引的元素
np.exp(s) #对序列元素进行计算
s*2
s+3
#当输入一个字典生成一个序列时,显式地指定index,若返回字典中与键index相对应的值,
没有对应的键值对,则返回null。字典长度与index的长度可以不一致
>>>dictionary={'a':2,'b':3,'c':4,'d':6,'e':8}
>>>temp=pd.Series(dictionary,index=['a','t','c','f'])
>>>temp
a 2
t NaN
c 4
f NaN
#可以就地修改序列的索引值index,此时需要保证输入的新的Index长度等于序列的长度,否则报错
dictionary={'a':1,'b':2}
obj=Series(dictionary)
obj.index=['c','d'] #将索引修改为c d
#DataFrame
The result index will be the union of the indexes of the various Series.
If there are any nested dicts, these will be first converted to Series.
If no columns are passed, the columns will be the sorted list of dict keys.
#通过字典生成,键值对形式指定列名及数据。key=columnname,value=value
col1=Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])#序列
col2=Series([1., 2., 3.], index=['a', 'b', 'c'])
k={'col1':col1,'col2':col2} #由字典生成数据框。字典的键作为列名,对应的序列作为数据输入,序列的索引就是数据框的行索引
DataFrame(k)
DataFrame(k, index=['d', 'b', 'a'], columns=['col1','col3']) #在创建数据框时候,允许对输入的行和列进行筛选。在数据中没有对应键的列将显示为null
-------------------
two three
d 4 NaN
b 2 NaN
a 1 NaN
---------------------
为某列进行赋值操作
>>>frm2
State year debt
1 Texas 2001 5
2 Oregon 2002 5
3 Utah 2003 5
4 California 2004 5
5 Ohio 2005 5
>>>debtval=Series([3.6,2.4,3.3],index=[1,3,5]) #debt列的值由一个序列指定,包含索引
>>>frm2['debt']=debtval#未能通过索引匹配的,没有值,返回NA
>>>frm2
State year debt
1 Texas 2001 3.6
2 Oregon 2002 NaN
3 Utah 2003 2.4
4 California 2004 NaN
5 Ohio 2005 3.3
为不存在的列赋值,则创建一个列
删除列:
del frm2['debt'] # del frm.debt 将会报错
d = {'one' : [1., 2., 3., 4.],'two' : [4., 3., 2., 1.]} #由列表指定各列的数值
DataFrame(d)
DataFrame(d,index=['a','b','c','d']) 此时需要保证显式指定的Index长度等于序列的长度,否则报错
DataFrame(data, columns=['C', 'A', 'B'])
#通过多个字典组成的列表生成
data2 = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]
DataFrame(data2, index=['first', 'second'])
-------------------
a b c
first 1 2 NaN
second 5 10 20
-------------------
#通过嵌套的字典定义
>>> dictionary={'Texas':{'year':2011,'debt':200},'Oregon':{'year':2011,'debt':300}}
>>> frm3=DataFrame(dictionary)
>>> frm3
Oregon Texas
debt 300 200
year 2011 2011
>>> frm3.T
debt year
Oregon 300 2011
Texas 200 2011
此时也可以显式地指定索引:
>>> frm3=DataFrame(dictionary,index=['year','debt','pop'])
>>> frm3
Oregon Texas
year 2011 2011
debt 300 200
pop NaN NaN
#从数据记录直接指定。数据记录的形式可以是元组tuple或者ndarray
DataFrame.from_records
data=array([(1, 2.0, 'Hello'), (2, 3.0, 'World')])
DataFrame.from_records(data,columns=['c','b','a'])
-----------------------
c b a
0 1 2.0 Hello
1 2 3.0 World
-----------------------
DataFrame.from_items
DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])]) #生成A B为列名的两列。orient='columns'
DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])],orient='index', columns=['one', 'two', 'three']) #以A B为索引,通过columns指定列名,不指定将报错
#对列进行操作:导出、新增、删除
df['three'] = df['one'] * df['two']
df['flag'] = df['one'] > 2
del df['two'] #通过del删除
three = df.pop('three')#通过pop删除
df['foo'] = 'bar' #一列取相同的值'bar‘
df['one_trunc'] = df['one'][:2] #取出one列的前两个值插入到新列one_trunc
#使用assign将会创建一个新的copy,原有数据框不会发生改变
iris.assign(sepal_ratio = iris['SepalWidth'] / iris['SepalLength'])#sepal_ratio通过SepalWidth/SepalLength计算而来
iris.assign(sepal_ratio = lambda x: (x['SepalWidth'] /x['SepalLength'])
EX:
iris.query('SepalLength > 5').assign(SepalRatio = lambda x: x.SepalWidth / x.SepalLength,PetalRatio = lambda x: x.PetalWidth / x.PetalLength)
#先取出SepalLength > 5的行,并且计算两个新列
NOTES:
# 无法完成,缺少对C的引用
df.assign(C = lambda x: x['A'] + x['B'],
D = lambda x: x['A'] + x['C'])
# 可以完成,先生成C再生成D
(df.assign(C = lambda x: x['A'] + x['B'])
.assign(D = lambda x: x['A'] + x['C']))
#数据框的连接和追加操作
>>>df_l=pd.DataFrame({'key':['a','a','b','b','c','d','d'],'value1':[1,2,3,4,6,7,9]})
>>>df_r=pd.DataFrame({'key':['a','a','b','c','e'],'value1':[9,12,3,8,5]})
>>> pd.merge(df_l,df_r,how='inner',on='key')
指定连接方式为内连接;
连接键为列‘key’,不显式指定此参数,将使用两个数据框中名称相同的列作为键;
返回的数据,仅包含左右数据中键的交集(即左右数据都存在的键)a b c
左集a对应多个数值,返回的数据集中全部包含
key value1_x value1_y
0 a 1 9
1 a 1 12
2 a 2 9
3 a 2 12
4 b 3 3
5 b 4 3
6 c 6 8
>>>pd.merge(df_l,df_r,how='left',on='key')
指定连接方式为左连接;
连接键为列‘key’,不显式指定此参数,将使用两个数据框中名称相同的列作为键;
返回的数据,仅包含左数据中键 a b c d,右集d没有对应故返回NA
左集a对应2个值,右集a对应2个值,所以返回的数据集中,a有4条记录(2*2)
key value1_x value1_y
0 a 1 9
1 a 1 12
2 a 2 9
3 a 2 12
4 b 3 3
5 b 4 3
6 c 6 8
7 d 7 NaN
8 d 9 NaN
指定多个连接键,使用列表指定参数on
>>> left=pd.DataFrame({'key1':[1,2,3],'key2':['a','b','c'],'val':[23,33,46]})
>>> right=pd.DataFrame({'key1':[1,2,2,3,4],'key2':['a','b','c','c','b'],'val':[22,46,89,29,88]})
>>> left
key1 key2 val
0 1 a 23
1 2 b 33
2 3 c 46
>>> right
key1 key2 val
0 1 a 22
1 2 b 46
2 2 c 89
3 3 c 29
4 4 b 88
>>> pd.merge(left,right,on=['key1','key2'],how='inner')
key1 key2 val_x val_y
0 1 a 23 22
1 2 b 33 46
2 3 c 46 29
>>> pd.merge(left,right,on=['key1','key2'],how='right')
key1 key2 val_x val_y
0 1 a 23 22
1 2 b 33 46
2 3 c 46 29
3 2 c NaN 89
4 4 b NaN 88
数据聚合运算(GROUP BY)
-------------------------------------------------------------------------------------
在传统SQL语法中,在进行聚合操作时,字段必须位于GROUP BY字句后或聚合函数内:
假设有如下逻辑的SQL语句:
select col1,col2,sum(data1),mean(data2) from df group by col1,col2
-------------------------------------------------------------------------------------
>>> df=pd.DataFrame({'col1':['a','a','b','b','a'],'col2':['one','two','one','one','two'],'data1':np.random.randn(5),'data2':np.random.randn(5)})
>>> df
col1 col2 data1 data2
0 a one 0.205309 -0.756663
1 a two 0.870956 0.756917
2 b one -0.026293 0.513525
3 b one 1.287029 -2.122978
4 a two 0.960200 1.937160
按col1和col2列进行聚合:
>>>grouped=df.groupby(['col1','col2']) #对col1和col2进行去重操作,得到唯一值
>>>grouped['data1','data2'].mean() #应用聚合函数,求data1和data2的平均值
data1 data2
col1 col2
a one 0.205309 -0.756663
two 0.915578 1.347038
b one 0.630368 -0.804727
>>>grouped=df.groupby(['col1','col2'])['data1'] #直接groupby之后指定要进行聚合计算的字段
>>>grouped.mean() #指定聚合函数
>>>grouped.data1.mean() #另一种写法
>>>grouped.size() #返回每个分组的计数,相当于count()聚合函数
col1 col2
a one 1
two 2
b one 2
还能通过某个列的函数值进行分组:
假设有数据
>>>df2=pd.DataFrame(np.random.randn(5),columns=['col1'],index=['a','bb','ccc','aa','c'])
col1
a 1.476153
bb -0.105215
ccc 1.749460
aa -1.359892
c -0.958026
>>>grouped=df2.groupby(len) #根据df2索引值的长度来进行分组
>>> grouped.mean()
col1
1 0.259064
2 -0.732554
3 1.749460
自定义聚合函数
def peak_2_peak(arr):
return arr.max()-arr.min()
grouped.agg(peak_2_peak)
聚合函数以字符串形式传入,针对不同列应用不同聚合函数
grouped.agg('mean')
grouped.agg(['mean','sum','std']) #不同的函数以列表形式传入
grouped=df.groupby(['col1','col2'])
grouped.agg([('data1','mean'),('data2','std')]) #针对不同列应用不同的函数,字段和函数名以元组方式传入,不同字段-函数的元组组成列表传入agg
将分组结果变成DF的其中一列
INTRODUCTION TO PANDAS
========================
圆括号是函数,方括号是索引
#Series data can be numpy array,or a python dict
#定义的方法:s = Series(data, index) #先指定数值再指定索引
无论选取何种方式都需要指定序列的长度,即元素的个数
s=Series(randn(5))
s = Series(randn(5), index=['a', 'b', 'c', 'd', 'e']) #索引的数量需要等于元素的数量,否则报错
d={'a':1,'b':2,'c':3}
s=Series(data=d,index=['b', 'c', 'd', 'a'])#显式地指定序列的索引值,输出的数据中,列已经排序。同时在数据中没有对应的键d则记为NULL
s=Series(5., index=['a', 'b', 'c', 'd', 'e'])#全部元素只有一个值
#序列元素的选取,索引始终保留
s[:3]
s[s > s.median()] #支持numpy的函数
s[s>3] #逻辑运算,取出大于3的元素
s[[1,2,4]] #由列表指定的元素
s[['a','b']] #由列表指定索引的元素
np.exp(s) #对序列元素进行计算
s*2
s+3
#当输入一个字典生成一个序列时,显式地指定index,若返回字典中与键index相对应的值,
没有对应的键值对,则返回null。字典长度与index的长度可以不一致
>>>dictionary={'a':2,'b':3,'c':4,'d':6,'e':8}
>>>temp=pd.Series(dictionary,index=['a','t','c','f'])
>>>temp
a 2
t NaN
c 4
f NaN
#可以就地修改序列的索引值index,此时需要保证输入的新的Index长度等于序列的长度,否则报错
dictionary={'a':1,'b':2}
obj=Series(dictionary)
obj.index=['c','d'] #将索引修改为c d
#DataFrame
The result index will be the union of the indexes of the various Series.
If there are any nested dicts, these will be first converted to Series.
If no columns are passed, the columns will be the sorted list of dict keys.
#通过字典生成,键值对形式指定列名及数据。key=columnname,value=value
col1=Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])#序列
col2=Series([1., 2., 3.], index=['a', 'b', 'c'])
k={'col1':col1,'col2':col2} #由字典生成数据框。字典的键作为列名,对应的序列作为数据输入,序列的索引就是数据框的行索引
DataFrame(k)
DataFrame(k, index=['d', 'b', 'a'], columns=['col1','col3']) #在创建数据框时候,允许对输入的行和列进行筛选。在数据中没有对应键的列将显示为null
-------------------
two three
d 4 NaN
b 2 NaN
a 1 NaN
---------------------
为某列进行赋值操作
>>>frm2
State year debt
1 Texas 2001 5
2 Oregon 2002 5
3 Utah 2003 5
4 California 2004 5
5 Ohio 2005 5
>>>debtval=Series([3.6,2.4,3.3],index=[1,3,5]) #debt列的值由一个序列指定,包含索引
>>>frm2['debt']=debtval#未能通过索引匹配的,没有值,返回NA
>>>frm2
State year debt
1 Texas 2001 3.6
2 Oregon 2002 NaN
3 Utah 2003 2.4
4 California 2004 NaN
5 Ohio 2005 3.3
为不存在的列赋值,则创建一个列
删除列:
del frm2['debt'] # del frm.debt 将会报错
d = {'one' : [1., 2., 3., 4.],'two' : [4., 3., 2., 1.]} #由列表指定各列的数值
DataFrame(d)
DataFrame(d,index=['a','b','c','d']) 此时需要保证显式指定的Index长度等于序列的长度,否则报错
DataFrame(data, columns=['C', 'A', 'B'])
#通过多个字典组成的列表生成
data2 = [{'a': 1, 'b': 2}, {'a': 5, 'b': 10, 'c': 20}]
DataFrame(data2, index=['first', 'second'])
-------------------
a b c
first 1 2 NaN
second 5 10 20
-------------------
#通过嵌套的字典定义
>>> dictionary={'Texas':{'year':2011,'debt':200},'Oregon':{'year':2011,'debt':300}}
>>> frm3=DataFrame(dictionary)
>>> frm3
Oregon Texas
debt 300 200
year 2011 2011
>>> frm3.T
debt year
Oregon 300 2011
Texas 200 2011
此时也可以显式地指定索引:
>>> frm3=DataFrame(dictionary,index=['year','debt','pop'])
>>> frm3
Oregon Texas
year 2011 2011
debt 300 200
pop NaN NaN
#从数据记录直接指定。数据记录的形式可以是元组tuple或者ndarray
DataFrame.from_records
data=array([(1, 2.0, 'Hello'), (2, 3.0, 'World')])
DataFrame.from_records(data,columns=['c','b','a'])
-----------------------
c b a
0 1 2.0 Hello
1 2 3.0 World
-----------------------
DataFrame.from_items
DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])]) #生成A B为列名的两列。orient='columns'
DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6])],orient='index', columns=['one', 'two', 'three']) #以A B为索引,通过columns指定列名,不指定将报错
#对列进行操作:导出、新增、删除
df['three'] = df['one'] * df['two']
df['flag'] = df['one'] > 2
del df['two'] #通过del删除
three = df.pop('three')#通过pop删除
df['foo'] = 'bar' #一列取相同的值'bar‘
df['one_trunc'] = df['one'][:2] #取出one列的前两个值插入到新列one_trunc
#使用assign将会创建一个新的copy,原有数据框不会发生改变
iris.assign(sepal_ratio = iris['SepalWidth'] / iris['SepalLength'])#sepal_ratio通过SepalWidth/SepalLength计算而来
iris.assign(sepal_ratio = lambda x: (x['SepalWidth'] /x['SepalLength'])
EX:
iris.query('SepalLength > 5').assign(SepalRatio = lambda x: x.SepalWidth / x.SepalLength,PetalRatio = lambda x: x.PetalWidth / x.PetalLength)
#先取出SepalLength > 5的行,并且计算两个新列
NOTES:
# 无法完成,缺少对C的引用
df.assign(C = lambda x: x['A'] + x['B'],
D = lambda x: x['A'] + x['C'])
# 可以完成,先生成C再生成D
(df.assign(C = lambda x: x['A'] + x['B'])
.assign(D = lambda x: x['A'] + x['C']))
#数据框的连接和追加操作
>>>df_l=pd.DataFrame({'key':['a','a','b','b','c','d','d'],'value1':[1,2,3,4,6,7,9]})
>>>df_r=pd.DataFrame({'key':['a','a','b','c','e'],'value1':[9,12,3,8,5]})
>>> pd.merge(df_l,df_r,how='inner',on='key')
指定连接方式为内连接;
连接键为列‘key’,不显式指定此参数,将使用两个数据框中名称相同的列作为键;
返回的数据,仅包含左右数据中键的交集(即左右数据都存在的键)a b c
左集a对应多个数值,返回的数据集中全部包含
key value1_x value1_y
0 a 1 9
1 a 1 12
2 a 2 9
3 a 2 12
4 b 3 3
5 b 4 3
6 c 6 8
>>>pd.merge(df_l,df_r,how='left',on='key')
指定连接方式为左连接;
连接键为列‘key’,不显式指定此参数,将使用两个数据框中名称相同的列作为键;
返回的数据,仅包含左数据中键 a b c d,右集d没有对应故返回NA
左集a对应2个值,右集a对应2个值,所以返回的数据集中,a有4条记录(2*2)
key value1_x value1_y
0 a 1 9
1 a 1 12
2 a 2 9
3 a 2 12
4 b 3 3
5 b 4 3
6 c 6 8
7 d 7 NaN
8 d 9 NaN
指定多个连接键,使用列表指定参数on
>>> left=pd.DataFrame({'key1':[1,2,3],'key2':['a','b','c'],'val':[23,33,46]})
>>> right=pd.DataFrame({'key1':[1,2,2,3,4],'key2':['a','b','c','c','b'],'val':[22,46,89,29,88]})
>>> left
key1 key2 val
0 1 a 23
1 2 b 33
2 3 c 46
>>> right
key1 key2 val
0 1 a 22
1 2 b 46
2 2 c 89
3 3 c 29
4 4 b 88
>>> pd.merge(left,right,on=['key1','key2'],how='inner')
key1 key2 val_x val_y
0 1 a 23 22
1 2 b 33 46
2 3 c 46 29
>>> pd.merge(left,right,on=['key1','key2'],how='right')
key1 key2 val_x val_y
0 1 a 23 22
1 2 b 33 46
2 3 c 46 29
3 2 c NaN 89
4 4 b NaN 88
数据聚合运算(GROUP BY)
-------------------------------------------------------------------------------------
在传统SQL语法中,在进行聚合操作时,字段必须位于GROUP BY字句后或聚合函数内:
假设有如下逻辑的SQL语句:
select col1,col2,sum(data1),mean(data2) from df group by col1,col2
-------------------------------------------------------------------------------------
>>> df=pd.DataFrame({'col1':['a','a','b','b','a'],'col2':['one','two','one','one','two'],'data1':np.random.randn(5),'data2':np.random.randn(5)})
>>> df
col1 col2 data1 data2
0 a one 0.205309 -0.756663
1 a two 0.870956 0.756917
2 b one -0.026293 0.513525
3 b one 1.287029 -2.122978
4 a two 0.960200 1.937160
按col1和col2列进行聚合:
>>>grouped=df.groupby(['col1','col2']) #对col1和col2进行去重操作,得到唯一值
>>>grouped['data1','data2'].mean() #应用聚合函数,求data1和data2的平均值
data1 data2
col1 col2
a one 0.205309 -0.756663
two 0.915578 1.347038
b one 0.630368 -0.804727
>>>grouped=df.groupby(['col1','col2'])['data1'] #直接groupby之后指定要进行聚合计算的字段
>>>grouped.mean() #指定聚合函数
>>>grouped.data1.mean() #另一种写法
>>>grouped.size() #返回每个分组的计数,相当于count()聚合函数
col1 col2
a one 1
two 2
b one 2
还能通过某个列的函数值进行分组:
假设有数据
>>>df2=pd.DataFrame(np.random.randn(5),columns=['col1'],index=['a','bb','ccc','aa','c'])
col1
a 1.476153
bb -0.105215
ccc 1.749460
aa -1.359892
c -0.958026
>>>grouped=df2.groupby(len) #根据df2索引值的长度来进行分组
>>> grouped.mean()
col1
1 0.259064
2 -0.732554
3 1.749460
自定义聚合函数
def peak_2_peak(arr):
return arr.max()-arr.min()
grouped.agg(peak_2_peak)
聚合函数以字符串形式传入,针对不同列应用不同聚合函数
grouped.agg('mean')
grouped.agg(['mean','sum','std']) #不同的函数以列表形式传入
grouped=df.groupby(['col1','col2'])
grouped.agg([('data1','mean'),('data2','std')]) #针对不同列应用不同的函数,字段和函数名以元组方式传入,不同字段-函数的元组组成列表传入agg
将分组结果变成DF的其中一列