Python之pandas学习笔记
1. Pandas数据结构
Series
带标签的一维同构数组,可存储整数、浮点数、字符串、Python 对象等类型的数据。轴标签统称为索引。
- 均匀数据
- 尺寸大小不变
- 数据的值可变
调用 pd.Series 函数即可创建 Series:s = pd.Series(data, index=index)
例1
a=pd.Series(np.random.randn(6),index=['A','B','C','D','E','F'])
print(a)
print(a.values)
print(a.index)
例2
a=pd.Series(np.random.randn(6),index=['A','B','C','D','E','F'])
print(a>0)
print(a[a>0])
print(np.exp(a[a>0]))
print('A' in a)
例3
import numpy as np
import pandas as pd
a=pd.Series(np.random.randn(6),index=['A','B','C','D','E','F'])
print(a)
print('\n')print(a[0])
print('\n')print(a[[0]])
print('\n')print(a[0],a[1])
print('\n')print(a[2:4])
print('\n')print(a[[3,0,4]])
print('\n')
注释:①#index= 是标签列;
②标签的列表里每个元素单引号不要忘了;
③index长度要与数据长度一样;
④如果索引值不指定,就会默认从0开始索引;
⑤a[0]与a[[0]]区别在于,a[0]直接输出索引0对应的数据,a[[0]]输出索引及数据;
⑥a[2:4]切片出索引及数据,左闭右开。
例2
dic={'a':0,'b':1,'c':2}
L=[1,2,3]
npy=np.random.randn(3)p_d0=pd.Series(dic)
print(dic)
print(p_d0)
print('\n')
p_d1=pd.Series(dic,index=list('ABC'))
print(p_d1)
print('\n')
p_d2=pd.Series(L,index=list('ABC'))
print(p_d2)
print('\n')
p_d3=pd.Series(npy,index=list('ABC'))
print(p_d3)
注释:①字典里的键值对可以直接将键作为索引;
②对字典里的值不能重新定义索引标签,列表和数组可以。
DataFrame
由多种类型的列构成的二维标签数据结构,既有灵活的行索引,又有灵活的列名。
- 异构数据
- 大小可变
- 数据可变
例1
import numpy as np
import pandas as pd
dic={'one':pd.Series([1,2,3],index=['a','b','c']),'two':pd.Series([1,2,3,4],index=['a','b','c','d'])}
a=pd.DataFrame(dic)
print(a)
print('\n')
b=pd.DataFrame(dic,index=['a','d','b'],columns=['two','a'])
print(b)
print('\n')
print(a.index)
print(a.columns)
print(b.index)
print(b.columns)
print('\n')
L=list(('mary','lenm','alibaba','jingd'))
c=pd.DataFrame(L,index=['a','b','c','d'],columns=['two'])
print(c)
注释:①index 和 columns 属性分别用于访问行、列标签;
②倒数第二行c的columns里,columns=[‘two’],如果写成columns=[‘two’,‘three’],不会得到three的一列是NaN的结果,而是报错,因为只有一列L。dic中是有两列Series。
例2
a=pd.DataFrame(np.random.randn(4,3),index=list('ABCD'),columns=['one','two','three'])
print(a)
- 嵌套字典
外层字典的键作为列,内层键作为行索引。
a={'Aedava':{2000:2.4,2002:2.9},'Ohio':{2000:1.5,2001:1.7,2002:3.6}}
pd.DataFrame(a)
- Series与DataFrame结合
data={'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],'year':[2000,2001,2002,2001,2002],'pop':[1.5,1.7,3.6,2.4,2.9]}
a=pd.DataFrame(data,columns=['year','state','pop','dept'],index=['one','two','three','four','five'])
print(a)
b=pd.Series(['-1.2','-1.5','-1.7'],index=['one','three','four'])
a['dept']=b #该行等价于a.iloc[:,3:]=b 等价于 a.loc[:,'dept']=b
print(a)
索引
- 推荐使用索引器:loc、iloc
loc显示取值切片,iloc隐式取值切片
例1
a=pd.Series(np.random.randn(5),index=list('12345'))
b=pd.Series(np.random.randn(5),index=list('abcde'))
print(a)
print('\n')
print(b)
print('\n')
print(a.loc['4']) #必须有引号
print(b.loc['a'])
print('\n')
print(a.iloc[4]) #不能有引号
print(b.iloc[0])
例2
a=np.random.randn(4,3)
b=pd.DataFrame(a,index=['class1','class2','class3','class4'],columns=['math','chine','sci'])
print(b)
print('\n')
print(b.loc[:'class3'])
print('\n')
print(b.loc[:'class3','chine':]) #逗号前是第0轴,逗号后是第1轴
print('\n')
print(b.iloc[:1,:]) #左闭右开
a=np.random.randn(4,3)
b=pd.DataFrame(a,index=['class1','class2','class3','class4'],columns=['math','chine','sci'])
print(b)
print('\n')
print(b.loc[b.mean(axis=1)>0.5]) #在列间比较,中位数大于0.5是3班
- 只选择行或列可以不用索引器
a=np.random.randn(4,3)
b=pd.DataFrame(a,index=['class1','class2','class3','class4'],columns=['math','chine','sci'])
print(b)
print('\n')
#print(b[0]) 报错
print(b[0:1])
print('\n')
c=pd.Series(np.random.randn(4),index=list('ABCD'))
print(c[0:2])
a=pd.DataFrame(np.random.randint(0,10,(3,3)),columns=list('ABC'))
print(a)
print('\n')
print(a[0:1])
print('\n')
# print(a[0]) 报错
# print(a[[0]]) 报错
print(a['A'])
print('\n')
print(a[['A']])
# print(a['A','B']) 报错
为了保险起见,用iloc[ , ]形式
a=pd.DataFrame(np.random.randint(0,10,(3,3)),columns=list('ABC'))
print(a)
print('\n')
print(a.iloc[0:1,:])
print(type(a.iloc[0:1,:])) #输出结果都是第一行,但类型不一样,一个是DataFrame,一个是Series
print(a.iloc[0,:])
print(type(a.iloc[0,:]))
- 重新索引
对行重新索引
data={'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],'year':[2000,2001,2002,2001,2002],'pop':[1.5,1.7,3.6,2.4,2.9]}
a=pd.DataFrame(data,columns=['year','state','pop','dept'],index=['one','two','three','four','five'])
print(a)
b=a.reindex(['one','two','six','three','four','five'])
print(b)
对列重新索引
data={'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],'year':[2000,2001,2002,2001,2002],'pop':[1.5,1.7,3.6,2.4,2.9]}
a=pd.DataFrame(data,columns=['year','state','pop','dept'],index=['one','two','three','four','five'])
print(a)
# b=a.reindex(['one','two','six','three','four','five'])
# print(b)
c=a.reindex(columns=['year','state','pop'])
c
- 丢掉指定轴上的项
data={'state':['Ohio','Ohio','Ohio','Nevada','Nevada'],'year':[2000,2001,2002,2001,2002],'pop':[1.5,1.7,3.6,2.4,2.9]}
a=pd.DataFrame(data,columns=['year','state','pop','dept'],index=['one','two','three','four','five'])
print(a)
print('\n')
print(a.drop(['one','four']))
print('\n')
print(a.drop(['pop','dept'],axis=1))
注释:默认删去行,也就是第0轴;
要删去列,加上axis=1.
- 一个例子明白如何直接添加数据帧的行或列
a,b,c = pd.DataFrame(list(range(5))),pd.DataFrame(list(range(1,6))),pd.DataFrame(list(range(3,8)))
d = pd.concat([a,b,c], axis=1,ignore_index=True)
d.columns=list("ABC")
d.index=list('abcde')
print(d)
print('\n')
d['1']=np.random.randint(0,10,5) #(1)
print(d)
d.loc[5]=np.random.randint(0,10,4) #(2)
d
注释:(1)(2)处说明了,添加列不需要索引器,直接在中括号里写上列名即可,列名要用引号;添加行我试过了必须要用索引器loc,中括号里直接写行名,行名不需要引号。
数值计算
- 索引对齐
a=pd.DataFrame(np.random.randint(0,10,(2,2)),columns=list('AB'))
b=pd.DataFrame(np.random.randint(0,10,(2,3)),columns=list('ABC'))
print(a)
print(b)
print(a+b)
a=pd.DataFrame(np.random.randint(0,10,(3,3)),columns=list('ABC'))
print(a)
# print(a-a.iloc[1])
print(a.loc[:,'A':'B'])
print(a-a.loc[:,'A':'B'])
- 广播
默认情况下,Seriesa.loc[0]的索引匹配到DataFrame的列,并沿着行往下广播
a=pd.DataFrame(np.random.randint(0,10,(3,3)),columns=list('ABC'))
print(a)
print(a.loc[0])
print(a-a.loc[0])
a=pd.DataFrame(np.random.randint(0,10,(3,3)),columns=list('ABC'))
print(a)
print('\n')
b=a['B']
c=a[['B']]
print(b) #形状是(3,)
print('\n')
print(c) #形状是(3,1)
print('\n')
print(np.shape(b))
print(np.shape(c))
print('\n')
print(a.subtract(b,axis=0))
print('\n')
print(a.subtract(b,axis=1))
print('\n')
print(a.subtract(c,axis=0))
print('\n')
print(a.subtract(c,axis=1))
注释:①对b的操作是广播,对c的操作是索引对齐;
②print(a.subtract(b,axis=0))是意义的,常用的。其他的我暂时还不太明白怎么减的。
处理缺失值
- 发现缺失值
a = pd.DataFrame([[1, 0, np.nan],[2, None, 3],[4, 5, 6]], dtype=np.float)
print(a.isnull())
- 剔除缺失值
a = pd.DataFrame([[1, 0, np.nan],[2, None, 3],[4, 5, 6]], dtype=np.float)
print(a)
print('\n')
print(a.dropna()) #dropna()默认丢弃任何含有缺失值的行
print('\n')
print(a[a.notnull()])
a = pd.DataFrame([[1, 0, np.nan],[2, None, 3],[4, 5, 6]], dtype=np.float)
a.dropna(axis=0, how='any')
注释:
DataFrame.dropna(axis = 0,how =‘any’,thresh = None,subset = None,inplace = False )
参数:
how : {‘any’,‘all’},默认’any’
‘any’:如果存在任何NA值,则删除该行或列。
‘all’:如果所有值都是NA,则删除该行或列。
thresh: 一行或者一列中最多有多少NaN
- 填充缺失值
a = pd.DataFrame([[1, 0, np.nan],[2, None, 3],[4, 5, 6]], dtype=np.float)
print(a)
print(a.fillna(0)) #0填充
print(a.fillna(method='backfill')) #向前填充
print(a.fillna(method='bfill')) #向前填充
print(a.fillna(method='pad')) #向后填充
print(a.fillna(method='ffill')) #向后填充
用聚合函数填充:
state=['Ohio','New York','Vermont','Florida','Oregion','Nevada','California','Idaho']
data=pd.DataFrame(np.random.randn(8),index=state)
data[::2]=np.nan
print(data)
print('\n')
group_key=['East']*4+['West']*4
a=data.groupby(group_key).mean()
print(a)
print('\n')
fill_mean=lambda x: x.fillna(x.mean())
data.groupby(group_key).apply(fill_mean)
注释:第1,3,5,7行的缺失值分别用根据group_key分组得到的平均值填充了。
合并与连接
- pd.concat()连接
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,keys=None, levels=None, names=None, verify_integrity=False,copy=True)
参数:
objs:Series,DataFrame或Panel对象的序列或映射。
axis:{0,1,…},默认为0。沿着连接的轴。
join:{‘inner’,‘outer’},默认为“outer”。
ignore_index:boolean,默认为False。
a=pd.DataFrame({'A':['A0','A1','A3','A4','A5'], #注意写入字典的格式'B':['B0','B1','B3','B4','B5'],'C':['C0','C1','C3','C4','C5'],'D':['D0','D1','D3','D4','D5']},index=list('12345'))
print(a)
print('\n')
b=pd.DataFrame({'A':['a0','a1','a3','a4','a5'],'B':['b0','b1','b3','b4','b5'],'C':['c0','c1','c3','c4','c5'],'E':['e0','e1','e3','e4','e5']},index=list('34567'))
print(b)
print('\n')
print(pd.concat([a,b])) #直接合并
print(pd.concat([a,b],join='inner')) #取交集
print(pd.concat([a,b],axis=1,join='inner')) #沿着第1轴取交集
print(pd.concat([a,b],ignore_index=True)) #合并后不用之前的索引
注释:pd.concat([a,b])默认沿着axis=0轴合并,
- pd.merge()合并
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=True)
参数:
left :DataFrame对象;
right:DataFrame对象;
on:连接的列名称,类似于MySQL中的外键;
left_on:左侧DataFrame中的列用作键,可以是列名或长度等于DataFrame长度的数组;
right_on:来自右的DataFrame的列作为键,可以是列名或长度等于DataFrame长度的数组;
left_index:如果为True,则使用左侧DataFrame中的索引(行标签)作为其连接键;
right_index:与右DataFrame的left_index具有相同的用法;
how:它是left, right, outer以及inner之中的一个,默认为inner,与MySQL表的联结相似;
sort:按照字典顺序通过连接键对结果DataFrame进行排序,默认为True。
参数on:
a=pd.DataFrame({'Class':['A0','A1','A3','A4','A5'],'Chine':['B0','B1','B3','B4','B5'],'Math':['C0','C1','C3','C4','C5'],'Sci':['D0','D1','D3','D4','D5']},index=list('12345'))
print(a)
print('\n')
b=pd.DataFrame({'Class':['A0','a1','A3','A4','a5'],'Chine':['B0','B1','B3','b4','b5'],'Math':['c0','c1','c3','c4','c5'],'Phy':['e0','e1','e3','e4','e5']},index=list('34567'))
print(b)
print('\n')
print(pd.merge(a,b,on='Chine'))
print(pd.merge(a,b,on=['Class','Chine']))
参数left_on right_on:
df1=pd.DataFrame({'lkey':['b','b','a','c','a','a','b'],'data1':range(7)})
df2=pd.DataFrame({'rkey':['a','b','d'],'data2':range(3)})
print(df1)
print('\n')
print(df2)
print('\n')
c=pd.merge(df1,df2,left_on='lkey',right_on='rkey')
print(c)
注释:df1与df2连接键中不共有的c行d行被删去;
left_on、right_on的用法与on类似,只不过on用在两个具有相同“外键”的DataFrame中,当df1与df2中的lkey、rkey在值的性质上一样(比如都代表等级),但列名又不一样,用on连接不了。
参数left_index=True、right_index=True:
df1=pd.DataFrame({'key':['a','b','a','a','b','c','d'],'value':range(7)})
df2=pd.DataFrame({'group':['3.5','6','7']},index=['a','b','c'])
print(df1)
print('\n')
print(df2)
print('\n')
c=pd.merge(df1,df2,left_on='key',right_index=True)
print(c)
注释:这两个参数表名索引被用作连接键。left_on='key',right_index=True
表示左边的连接键是key,右边的连接键是其索引;
生成的数据帧索引按照左边的,不是重新索引。
参数how:
a=pd.DataFrame({'Class':['A0','A1','A3','A4','A5'],'Chine':['B0','B1','B3','B4','B5'],'Math':['C0','C1','C3','C4','C5'],'Sci':['D0','D1','D3','D4','D5']},index=list('12345'))
print(a)
print('\n')
b=pd.DataFrame({'Class':['A0','a1','A3','A4','a5'],'Chine':['B0','B1','B3','b4','b5'],'Math':['c0','c1','c3','c4','c5'],'Phy':['e0','e1','e3','e4','e5']},index=list('34567'))
print(b)
print('\n')
print(pd.merge(a,b,on='Class',how='left'))
print('\n')
print(pd.merge(a,b,on='Class',how='right'))
print('\n')
print(pd.merge(a,b,on='Class',how='outer'))
- 层次化索引
将1个以上的连接键放在列表里:
df1=pd.DataFrame({'key1':['ohio','ohio','ohio','nevada','nevada'],'key2':[2000,2001,2002,2001,2002],'data':np.arange(5)})
df2=pd.DataFrame(np.arange(12).reshape(6,2),index=[['nevada','nevada','ohio','ohio','ohio','ohio'],[2001,2000,2000,2000,2001,2002]],columns=['event1','event2'])
print(df1)
print('\n')
print(df2)
print('\n')
c=pd.merge(df1,df2,left_on=['key1','key2'],right_index=True)
print(c)
df1=pd.DataFrame([[1,2],[3,4],[5,6]],index=['a','c','e'],columns=['ohio','nevada'])
df2=pd.DataFrame([[7,8],[9,10],[11,12],[13,14]],index=['b','c','d','e'],columns=['missouri','alabama'])
print(df1)
print('\n')
print(df2)
print('\n')
c=pd.merge(df1,df2,how='outer',left_index=True,right_index=True)
print(c)
数据转换
- 数据重复
data=pd.DataFrame({'k1':['one']*3+['two']*4,'key2':[1,1,2,3,3,4,4]})
print(data)
print('\n')
a=data.duplicated() #向前瞻望是否有重复行
print(a)
print('\n')
b=data.drop_duplicates() #删除重复行,返回DataFrame
print(b)
data['k3']=np.arange(7)
print(data)
print('\n')
print(data.drop_duplicates('k1')) #按照k1列删除重复值的行
print(data.drop_duplicates('key2')) #按照key2列删除重复值的行
print(data.drop_duplicates(['k1','key2']))
- 利用函数或映射进行数据转换
data=pd.DataFrame({'food':['bacon','pulled pork','bacon','Pastrami','corned beef','Bacon','pastrami','honey ham','nova lax'],'ounces':[4,3,12,6,7.5,8,3,5,6]})
print(data)
print('\n')
meat_to_animal={'bacon':'pig','pulled pork':'pig','pastrami':'cow','corned beef':'cow','honey ham':'pig','nova lax':'salmon'}
#print(meat_to_animal)
#print('\n')
data['animal']=data['food'].map(str.lower).map(meat_to_animal)
data
注释:这里map函数好好看看,如果不用map函数得到这样的结果如下:
data=pd.DataFrame({'food':['bacon','pulled pork','bacon','Pastrami','corned beef','Bacon','pastrami','honey ham','nova lax'],'ounces':[4,3,12,6,7.5,8,3,5,6]})
print(data)
print('\n')
meat_to_animal=pd.DataFrame(['pig','pig','cow','cow','pig','salmon'],index=['bacon','pulled pork','pastrami','corned beef','honey ham','nova lax'])
print(meat_to_animal)
print('\n')
data['food']=data['food'].map(str.lower)
c=pd.merge(data,meat_to_animal,left_on='food',right_index=True)
c# data.drop(columns=['food'],axis=1,inplace=True)
# print(data)
# data['animal']=data['food'].map(str.lower)
# pd.drop(data['food']) ×
# data.drop(columns=['food'],axis=1,inplace=True) √
# print(data)
# print('\n')
# c=pd.merge(data,meat_to_animal,left_on='food',right_index=True)
# c
可以看到,虽然得到类似结果,但过程有点麻烦,而且要将food首字母变小写的结果保留,并且最后的索引并未排序,注意,merge中没有concat里的ignore_index=True。而且注意删除数据帧的某列,用data.drop(columns=['food'],axis=1)
,注释的部分是写过程中的错误。
- 替换值
data=pd.DataFrame([1,-999,2,-999,3,-1000])
print(data)
print('\n')
a=data.replace(-999,np.nan)
print(a)
print('\n')
b=data.replace([-999,-1000],np.nan)
print(b)
print('\n')
d=data.replace([-999,-1000],[np.nan,0])
d
数据聚合与分组运算
groupby基本操作
- 分组聚合(axis=0)
- 指定用于聚合的数值列
df=pd.DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randn(5),'data2':np.random.randn(5)})
print(df)
print('\n')
df['data1'].groupby(df['key1']) #(1)
注释:①df.groupby(df[‘key1’])会报错,想想,只按照key1进行分组,然后呢,要干什么呢,在SAS中的proc mean后面跟着groupby variable-name,是因为proc mean过程就是计算一些统计量了,在MySQL中,groupby往往也与一些聚合函数等一起用,因为你并不是只分组(如果只分组,那排序不就好了),而是分组计算某个特征值,所以单纯的df.groupby(df[‘key1’])肯定报错;
②指定key1列分组还可以写成grouped=df.groupby(df['key1'])['data1'].mean()
,可用于已经分组的情形;
③(1)是一个对象,其结果并没有什么东西,但是已经包含了接下来对分组执行运算的一些信息。例如计算data1列的均值:
比如按key1分组的均值:
grouped=df['data1'].groupby(df['key1'])
grouped.mean()
多层次分组计算均值:
df=pd.DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randint(0,10,5),'data2':np.random.randn(5)})
print(df)
print('\n')
grouped=df['data1'].groupby([df['key1'],df['key2']])
a=grouped.mean()
print(a)
print('\n')
grouped_1=df['data2'].groupby([df['key1'],df['key2']])
b=grouped_1.mean()
print(b)
分组键可以不是数据帧里的键,可以是长度适当的数组:
df=pd.DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randint(0,10,5),'data2':np.random.randn(5)})
print(df)
print('\n')
state=np.array(['Ohio','California','California','Ohio','Ohio'])
year=np.array([2005,2005,2006,2005,2006])
df['data1'].groupby([state,year]).mean()
- 不指定用于聚合的数值列
df=pd.DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randint(0,10,5),'data2':np.random.randn(5)})
print(df)
print('\n')
print(df.groupby(df['key1']).mean())
print(df.groupby([df['key1'],df['key2']]).mean())
- 分组聚合(axis=1)
df=pd.DataFrame(np.arange(25).reshape(5,5),index=['Joe','Steve','Wes','Jim','Travis'],columns=['a','b','c','d','e'])
print(df)
print('\n')
df.iloc[2:3,1:3]=np.nan #将值11,12替换成空值
print(df)
print('\n')
mapping={'a':'red','b':'red','c':'blue','d':'blue','e':'red','f':'orange'}
a=df.groupby(mapping,axis=1) #(1)
print(a) #输出结果表示分组成功
print('\n')
print(a.sum())
print(a.mean())
df # (2)
注释:根据df最后的输出结果表明,(1)处并没有替换列名,而是根据mapping对axis=1分组,也就是横向计算,之前是纵向。
- 遍历分组
遍历打印key1的每个组:
df=pd.DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randint(0,10,5),'data2':np.random.randn(5)})
print(df)
print('\n')
# print(df.groupby('key1'))
for i,j in df.groupby('key1'):print(i)print(j)
遍历打印组合分组:
df=pd.DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randint(0,10,5),'data2':np.random.randn(5)})
print(df)
print('\n')
# print(df.groupby('key1'))
# for i,j in df.groupby('key1'): #(1
# print(i)
# print(j)
# print('\n')
for (i,j),k in df.groupby(['key1','key2']): print(i,j)print(k)
data =pd.DataFrame({'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings','kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],'Points':[876,789,863,673,741,812,756,788,694,701,804,690]})
# print(data)
grouped=data.groupby(['Year'])
for name in grouped: # (2)print(name) #这两个for遍历区别不知道在哪
for name,year in grouped: # (3)print(name)print(year)
注释:原本以为(1)中for循环的i,j代表组key1的两个组类别,但发现(3)中组year的组类别不止两个,结合(2),感觉就是输出好看些?
4.选择一个分组
data =pd.DataFrame({'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings','kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],'Points':[876,789,863,673,741,812,756,788,694,701,804,690]})
grouped=data.groupby(['Year'])
print(grouped.get_group(2016))
聚合
可以对分组后的其他列进行聚合,也可以对分组后得部分列聚合,聚合函数不一定一样。
a=pd.DataFrame({'Team':['Riders', 'Riders', 'Devils', 'Devils', 'Kings','kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],'Rank':[1, 2, 2,3, 3,4 ,1,1,2 , 4,1,2],'Year':[2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],'Points':[876,789,863,673,741,812,756,788,694,701,804,690]})
print(a)
print('\n')
b=a.groupby('Year')
print(b)
print('\n')
print(b.agg(['min','mean','max'])) #这里只输出Points和Rank的统计值是因为Team不是数值,不然也会输出
print('\n')
print(b.agg({'Points':['min','max','mean']})) #只输出分组后Points列的统计量,注意这里存放方式是字典
传入agg()可以使用自定义的函数:
def max_to_min(a):return a.max()-a.min()df=pd.DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randint(0,10,5),'data2':np.random.randn(5)})
print(df)
print('\n')
grouped=df.groupby(df['key1'])
grouped.agg(max_to_min)
过滤
df = pd.DataFrame({'key': list('ABCABC'),'data1': range(6),'data2': np.random.randint(0,10,6)})
print(df)
print(df.groupby('key').sum())
a=df.groupby('key').filter(lambda x: x['data1'].sum() > 4)
print(a)
转换transform
transform将一个函数应用到各个分组
df=pd.DataFrame(np.arange(25).reshape(5,5),index=['Joe','Steve','Wes','Jim','Travis'],columns=['a','b','c','d','e'])
print(df)
print('\n')
key=['one','two','one','two','one']
print(df.groupby(key).mean()) #这里默认axis=0,也就是将Joe,Steve等替换成key
df.groupby(key).transform(np.mean)
按照key距平化:
def stand(a):return a-a.mean()df=pd.DataFrame(np.arange(35).reshape(5,7),index=['Joe','Steve','Wes','Jim','Travis'],columns=['a','b','c','d','e','f','g'])
print(df)
print('\n')
key=['one','two','one','one','two']
# print(df.groupby(key).stand()) #报错
grouped=df.groupby(key).transform(stand)
grouped
应用apply
a=pd.DataFrame(np.random.randn(4,3),index=['one','two','three','four'])
print(a)
print(np.abs(a))
a=pd.DataFrame(np.random.randn(4,3),index=['one','two','three','four'])
print(a)
print('\n')
f=lambda x: x.max()-x.min()
print(a.apply(f)) #默认axis=0
print('\n')
print(a.apply(f,axis=1))
读取文件
读取文本格式文件
- read_csv
pd.read_csv('E:/Python数据/1.csv') #报错
因为路径中有中文,加上engine='python’就行;或者把文件路径改成全英文。
pd.read_csv('E:/Python数据/1.csv',engine='python')
我的csv文档里的数据如下:
但显然上面的输出,将第一行数据作为索引了,如果不要,就加上header=None,注意大小写。
pd.read_csv('E:/PythonData/1.csv',header=None)
- read_table
用read_table读取上述文件,加上sep=’,'即可
pd.read_table('E:/PythonData/1.csv',header=None,sep=',')
加上列的索引不能用columns,用names:
pd.read_csv('E:/PythonData/1.csv',names=['a','b','c','d','message'])
如果要将message列作为行的索引:
pd.read_csv('E:/PythonData/1.csv',names=
['a','b','c','d','message'],index_col='message')
如果作多层次行的索引:
a = pd.read_csv('E:/PythonData/1.csv',names=['key1','key2','value1','value2'],index_col=['key1','key2'])
a
如果要自定义行索引名,除了用表里面的列,还可以回归到pandas的索引赋值:
a = pd.read_csv('E:/PythonData/1.csv',names=['key1','key2','value1','value2'])
a.index = list('12345678')
a
读取Excel格式文件
没有header=None选项,路径是中文没关系。
将路径下41个副本文件名换成variable_list.xls表中第二列的值
import pandas as pd
import os
a=pd.read_excel('E:\\研究生课程\\应用统计案例分析\\death_poll\\variable_list.xls') #直接读取
b=a.iloc[:,2] #将第二列的值读出来
c=list(b) #转换成列表
print(c)
# b[0] #实验了一下第一个
path="E:\研究生课程\应用统计案例分析\death_poll\deathquantity"
dirs=os.listdir(path) ##41个原文件的.csv名
dirs
for i,j in zip(range(len(c)),range(len(dirs))):os.renames(r"E:\研究生课程\应用统计案例分析\death_poll\deathquantity\\"+dirs[i],r"E:\研究生课程\应用统计案例分析\death_poll\deathquantity\\"+c[j]+".csv")
# os.renames(f"E:\研究生课程\应用统计案例分析\death_poll\deathquantity\{dirs[i]}",
# f"E:\研究生课程\应用统计案例分析\death_poll\deathquantity\{c[j]}.csv")
# os.renames(os.path.join("E:\研究生课程\应用统计案例分析\death_poll\deathquantity",dirs[i]),
# os.path.join("E:\研究生课程\应用统计案例分析\death_poll\deathquantity",c[j]+".csv"))
注释:①重命名的文件名中不可以有空格,os.renames(old-filename,new-filename)
最后四行注释的两种方法也可以重命名成功,但三者之间有区别:
用"E:\研究生课程\应用统计案例分析\death_poll\deathquantity\“时,注意最后要再加个斜杠;
用f"E:\研究生课程\应用统计案例分析\death_poll\deathquantity{c[j]}.csv”
注意格式化的部分是{c[j]},前后不需要加号;
用 os.path.join(“E:\研究生课程\应用统计案例分析\death_poll\deathquantity”,c[j]+".csv")) 最方便,不用再路径最后多加一个斜杠,也不用格式化,但是.csv的后缀与前面要用加号,用os.path.join(“E:\研究生课程\应用统计案例分析\death_poll\deathquantity”,c[j]),".csv") 就报错。
②zip(a,b)函数,使a与b中索引相对应:
a = [1,2,3,4,5]
b = [6,7,8,9,10]
print(dict(zip(a,b)))
print(list(zip(a,b)))
在for循环中,后面只能有一个迭代器,写成for i,j in range(len©),range(len©)就报错。
一个小游戏
打牌的游戏:#H红心,S黑桃,C梅花,D方块
suits=['H','S','C','D']
card_val=(list(range(1,11))+[10]*3)*4
base_name=['A']+list(range(2,11))+['J','Q','K']
cards=[]
for suit in suits:cards.extend(str(num)+suit for num in base_name)
deck=pd.DataFrame(card_val,index=cards) #索引是牌名,列值是点数
print(deck[:13])
#从这副牌中抽出5张
def draw(deck):return deck.take(np.random.permutation(len(deck)[:5])) #len(deck)=52 (1)
print(draw(deck))
注释:抽出5张牌,其点数分别是10,1,5,8,6
①np.random.permutation(),输入整数或列表,返回一个乱序的序列;输入数组,返回乱序的数组:
np.random.permutation([1,2,3,4,5])
np.random.permutation(10)
np.random.permutation(np.arange(10))
②pd.DataFrame.take() 括号里只能填索引,且是隐形索引值,
#deck.take([0,5]) #取出索引号为0和5的Series
Python之pandas学习笔记相关推荐
- 学习python的pandas学习笔记记录
分分钟搞定pandas (cookbook) http://pandas.pydata.org/pandas-docs/stable/cookbook.html#cookbook http://www ...
- Python基础知识学习笔记——Matplotlib绘图
Python基础知识学习笔记--Matplotlib绘图 整理python笔记,以防忘记 文章目录 Python基础知识学习笔记--Matplotlib绘图 一.绘图和可视化 1.导入模块 2.一个简 ...
- Python——常用Python包的学习笔记
1 致谢 感谢陈助教的帮助! 2 前言 今天想通过画图展现一下学习参考值的变化情况,在网上看了一下,需要使用plt包,不过又忘了plt是做什么用的了,于是想要记录一下,写一下关于常用Python包的笔 ...
- Python最优化算法学习笔记(Gurobi)
微信公众号:数学建模与人工智能 github地址:https://github.com/QInzhengk/Math-Model-and-Machine-Learning Python最优化算法学习笔 ...
- python数据分析入门学习笔记
python数据分析入门学习笔记儿 学习利用python进行数据分析的笔记儿&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我 ...
- pandas学习笔记之DateFrame
pandas学习笔记之DateFrame 文章目录 pandas学习笔记之DateFrame 1.DateFrame的创建 1)认识DataFrame对象 2)由二维列表创建(默认index和colu ...
- [Pandas 学习笔记] - No.1 pandas学习笔记
pandas学习笔记 pandas是基于numpy开发出的数据分析包,用于高效地操作大型数据集.pandas的数据结构有三种 分别为 series,dataframe和panel,对应一维,二维,三维 ...
- Python量化交易学习笔记(1)
Python量化交易学习笔记(1) http://zwpython.com/ http://www.topquant.vip/?p=2275 [更多参见] <zwPython,目前最好的py开发 ...
- pandas学习笔记之Series
pandas学习笔记之Series 文章目录 pandas学习笔记之Series pandas中Series的创建 1)用python中的列表list创建: 2)用numpy数组创建 3)用pytho ...
- python嵩天课堂笔记_[Python机器学习]强化学习笔记(嵩天礼欣老师mooc第三周)
[Python机器学习]强化学习笔记(嵩天礼欣老师mooc第三周) [Python机器学习]强化学习笔记(嵩天礼欣老师mooc第三周) 目录 强化学习 定义 马尔科夫决策过程 基本元素 值函数 最优值 ...
最新文章
- JSON http://www.cnblogs.com/haippy/archive/2012/05/20/2509329.html
- 淮北师范大学计算机学院在哪个校区,2021年淮北师范大学信息学院有几个校区,大一新生在哪个校区...
- mysql触发器的简单写法
- everedit选择_EverEdit(文本编辑器)
- Java for循环改数据_如何改变arrs数组?当然是需用for循环啦
- 【报告分享】2022电商行业趋势报告.pdf
- Amadeus Pro for Mac(多轨音频编辑器)
- 框架设计--第八章 动态SQL--习题答案
- RUNA WFE,workflow environment based on JBoss' JBPM engine
- 大数据用什么软件python_大数据软件 python
- 安科瑞预付费系统在电力系统中的应用
- cod16与战网服务器连接中断,《使命召唤16》无法连接服务器怎么解决 服务器连接解决攻略...
- 一家企业怎样才算Cool?Gartner告诉你!
- 火炬开发区理工学校计算机等级考,我校召开2018下半年全国计算机等级考试考务工作会...
- 详解react生命周期
- 坚持高质量发展:春风动力搭建项目全生命周期管理信息化平台
- SAP License:金审系统与SAP接口
- 使用sysbench进行压测达梦V8数据库
- 不协调的世界(3)-高速公路
- Ajax(阿贾克斯)基础
热门文章
- 01数据分析与Excel
- 数字孪生交通仿真(一)
- 新团队团队融合研讨会_新的网络研讨会:如何避免持续交付的隐性成本
- 电脑仙人掌机器人作文_蜗牛、仙人掌、电脑、雪人、机器人、蚕宝宝、大象选三到四个词作文...
- Sqoop基于时间列的增量数据之LastModified方式
- 2021西安ec final游记
- php生成拟合线,excel拟合曲线怎么做
- 股指期货日内平仓手续费高,锁仓可以解决吗
- 泰坦尼克号生存预测python毕设_机器学习入门案例分析-泰坦尼克号生存预测
- 《GCAMatting:Natural Image Matting via Guided Contextual Attention》