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基本操作
  1. 分组聚合(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())

  1. 分组聚合(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分组,也就是横向计算,之前是纵向。

  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学习笔记相关推荐

  1. 学习python的pandas学习笔记记录

    分分钟搞定pandas (cookbook) http://pandas.pydata.org/pandas-docs/stable/cookbook.html#cookbook http://www ...

  2. Python基础知识学习笔记——Matplotlib绘图

    Python基础知识学习笔记--Matplotlib绘图 整理python笔记,以防忘记 文章目录 Python基础知识学习笔记--Matplotlib绘图 一.绘图和可视化 1.导入模块 2.一个简 ...

  3. Python——常用Python包的学习笔记

    1 致谢 感谢陈助教的帮助! 2 前言 今天想通过画图展现一下学习参考值的变化情况,在网上看了一下,需要使用plt包,不过又忘了plt是做什么用的了,于是想要记录一下,写一下关于常用Python包的笔 ...

  4. Python最优化算法学习笔记(Gurobi)

    微信公众号:数学建模与人工智能 github地址:https://github.com/QInzhengk/Math-Model-and-Machine-Learning Python最优化算法学习笔 ...

  5. python数据分析入门学习笔记

    python数据分析入门学习笔记儿 学习利用python进行数据分析的笔记儿&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我 ...

  6. pandas学习笔记之DateFrame

    pandas学习笔记之DateFrame 文章目录 pandas学习笔记之DateFrame 1.DateFrame的创建 1)认识DataFrame对象 2)由二维列表创建(默认index和colu ...

  7. [Pandas 学习笔记] - No.1 pandas学习笔记

    pandas学习笔记 pandas是基于numpy开发出的数据分析包,用于高效地操作大型数据集.pandas的数据结构有三种 分别为 series,dataframe和panel,对应一维,二维,三维 ...

  8. Python量化交易学习笔记(1)

    Python量化交易学习笔记(1) http://zwpython.com/ http://www.topquant.vip/?p=2275 [更多参见] <zwPython,目前最好的py开发 ...

  9. pandas学习笔记之Series

    pandas学习笔记之Series 文章目录 pandas学习笔记之Series pandas中Series的创建 1)用python中的列表list创建: 2)用numpy数组创建 3)用pytho ...

  10. python嵩天课堂笔记_[Python机器学习]强化学习笔记(嵩天礼欣老师mooc第三周)

    [Python机器学习]强化学习笔记(嵩天礼欣老师mooc第三周) [Python机器学习]强化学习笔记(嵩天礼欣老师mooc第三周) 目录 强化学习 定义 马尔科夫决策过程 基本元素 值函数 最优值 ...

最新文章

  1. JSON http://www.cnblogs.com/haippy/archive/2012/05/20/2509329.html
  2. 淮北师范大学计算机学院在哪个校区,2021年淮北师范大学信息学院有几个校区,大一新生在哪个校区...
  3. mysql触发器的简单写法
  4. everedit选择_EverEdit(文本编辑器)
  5. Java for循环改数据_如何改变arrs数组?当然是需用for循环啦
  6. 【报告分享】2022电商行业趋势报告.pdf
  7. Amadeus Pro for Mac(多轨音频编辑器)
  8. 框架设计--第八章 动态SQL--习题答案
  9. RUNA WFE,workflow environment based on JBoss' JBPM engine
  10. 大数据用什么软件python_大数据软件 python
  11. 安科瑞预付费系统在电力系统中的应用
  12. cod16与战网服务器连接中断,《使命召唤16》无法连接服务器怎么解决 服务器连接解决攻略...
  13. 一家企业怎样才算Cool?Gartner告诉你!
  14. 火炬开发区理工学校计算机等级考,我校召开2018下半年全国计算机等级考试考务工作会...
  15. 详解react生命周期
  16. 坚持高质量发展:春风动力搭建项目全生命周期管理信息化平台
  17. SAP License:金审系统与SAP接口
  18. 使用sysbench进行压测达梦V8数据库
  19. 不协调的世界(3)-高速公路
  20. Ajax(阿贾克斯)基础

热门文章

  1. 01数据分析与Excel
  2. 数字孪生交通仿真(一)
  3. 新团队团队融合研讨会_新的网络研讨会:如何避免持续交付的隐性成本
  4. 电脑仙人掌机器人作文_蜗牛、仙人掌、电脑、雪人、机器人、蚕宝宝、大象选三到四个词作文...
  5. Sqoop基于时间列的增量数据之LastModified方式
  6. 2021西安ec final游记
  7. php生成拟合线,excel拟合曲线怎么做
  8. 股指期货日内平仓手续费高,锁仓可以解决吗
  9. 泰坦尼克号生存预测python毕设_机器学习入门案例分析-泰坦尼克号生存预测
  10. 《GCAMatting:Natural Image Matting via Guided Contextual Attention》