Pandas快速入门
一.Pandas基本介绍
1.Numpy和Pandas的异同
如果用 python 的列表和字典来作比较, 那么可以说 Numpy 是列表形式的,没有数值标签,而 Pandas 就是字典形式。Pandas是基于Numpy构建的,让Numpy为中心的应用变得更加简单。要使用pandas,首先需要了解他主要两个数据结构:Series和DataFrame。
2.Series
Series的字符串表现形式为:索引在左边,值在右边。由于我们没有为数据指定索引。于是会自动创建一个0到N-1(N为长度)的整数型索引。
import numpy as np
import pandas as pd
s=pd.Series([1,2,3,4])
print(s)
'''
0 1
1 2
2 3
3 4
dtype: int64
'''
3.DataFrame
DataFrame是一个表格型的数据结构,它包含有一组有序的列,每列可以是不同的值类型(数值,字符串,布尔值等)。DataFrame既有行索引也有列索引, 它可以被看做由Series组成的大字典。
import numpy as np
import pandas as pd
dates=pd.date_range('20180930',periods=6)
df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=['a','b','c','d'])
print(df)
'''
a b c d
2018-09-30 1.993737 1.309212 -0.948103 1.021250
2018-10-01 -1.019824 0.172133 0.173929 0.646952
2018-10-02 0.623758 1.236775 -0.221444 -0.477707
2018-10-03 0.124593 0.843158 1.099162 -0.520331
2018-10-04 0.099328 0.998525 2.023019 2.174637
2018-10-05 0.293913 -2.181669 -0.180980 0.050529
'''
(1) df的两种生成方式
- 创建一组没有给定行标签和列标签的数据 df1,这样,他就会采取默认的从0开始 index;
- 也可以用字典的方式创建
(2)获取DataFrame的列名是一个比较简单的操作,又以下几个方法:
- [column for column in df]
- df.columns.values 返回 array, 可以通过 tolist(), 或者 list(array) 转换为list,一般 tolist()效率更高。
- list(df)
- df.columns 返回Index,可以通过 tolist(), 或者 list(array) 转换为list
(3)DataFrame的简单应用
- 查看表中数据中的属性:df2.dtypes
- 查看表的行号:df2.index
- 查看表的列号:如(2)中介绍
- 只想查看表中的具体数据:df2.values
- 得到表中数据的总结:df2.describe()
- 翻转数据:df2.T
- 对数据按照columns进行排序输出:df2.sort_index(axis=1,ascending=False),后面代表降序排列
- 对数据值进行排序输出:df.sort_values(by='E')
import numpy as np
import pandas as pd
#df第一种创建方式
df1=pd.DataFrame(np.arange(12).reshape((3,4)))
print(df1)
'''
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
'''
#df第二种创建方式
df2=pd.DataFrame(
{
'A':1,
'B':pd.Timestamp('20180930'),
'C':pd.Series(1,index=list(range(4)),dtype='float32'),
'D':np.array([3]*4,dtype='int32'),
'E':pd.Categorical(['test','train','test','train']),
'F':'foo'
}
)
print(df2)
'''
A B C D E F
0 1 2018-09-30 1.0 3 test foo
1 1 2018-09-30 1.0 3 train foo
2 1 2018-09-30 1.0 3 test foo
3 1 2018-09-30 1.0 3 train foo
'''
#1.查看表中数据中的属性
print(df2.dtypes)
'''
A int64
B datetime64[ns]
C float32
D int32
E category
F object
dtype: object
'''
#2.查看表的行号
print(df2.index)
'''
Int64Index([0, 1, 2, 3], dtype='int64')
'''
#3.查看表的列号
print(list(df2.columns.values))
'''
['A', 'B', 'C', 'D', 'E', 'F']
'''
#4.只想查看表中的具体数据
print(df2.values)
'''
[[1 Timestamp('2018-09-30 00:00:00') 1.0 3 'test' 'foo']
[1 Timestamp('2018-09-30 00:00:00') 1.0 3 'train' 'foo']
[1 Timestamp('2018-09-30 00:00:00') 1.0 3 'test' 'foo']
[1 Timestamp('2018-09-30 00:00:00') 1.0 3 'train' 'foo']]
'''
#5.得到表中数据的总结
print(df2.describe())
#6.翻转数据
print(df2.T)
#7.对数据按照columns进行排序输出
print(df2.sort_index(axis=1,ascending=False))
'''
F E D C B A
0 foo test 3 1.0 2018-09-30 1
1 foo train 3 1.0 2018-09-30 1
2 foo test 3 1.0 2018-09-30 1
3 foo train 3 1.0 2018-09-30 1
'''
#8.对数据值进行排序输出
print(df2.sort_values(by='E'))
'''
A B C D E F
0 1 2018-09-30 1.0 3 test foo
2 1 2018-09-30 1.0 3 test foo
1 1 2018-09-30 1.0 3 train foo
3 1 2018-09-30 1.0 3 train foo
'''
二.Pandas选择数据
1.简单筛选
- df['列名/行名']或者df.列名/行名;
- 让选择跨越多行多列,和list切片操作一样,注意df[3:3]将会是空对象,但如果里面两个都是具体的标签数据,会包含这两个标签数据以及之间的内容
import numpy as np
import pandas as pd
dates=pd.date_range('20180930',periods=6)
df=pd.DataFrame(np.arange(24).reshape(6,4),index=dates,columns=['A','B','C','D'])
#1.两者效果一致
print(df['A'])
print(df.A)
'''
2018-09-30 0
2018-10-01 4
2018-10-02 8
2018-10-03 12
2018-10-04 16
2018-10-05 20
Freq: D, Name: A, dtype: int32
'''
print(df[0:3])
'''
A B C D
2018-09-30 0 1 2 3
2018-10-01 4 5 6 7
2018-10-02 8 9 10 11
'''
print(df['20181001':'20181003'])
'''
A B C D
2018-10-01 4 5 6 7
2018-10-02 8 9 10 11
2018-10-03 12 13 14 15
'''
2.根据loc(使用标签寻找)
可以使用标签来选择数据 loc, 本例子主要通过标签名字选择某一行数据, 或者通过选择某行或者所有行(:代表所有行)然后选其中某一列或几列数据。
import numpy as np
import pandas as pd
dates=pd.date_range('20180930',periods=6)
df=pd.DataFrame(np.arange(24).reshape(6,4),index=dates,columns=['A','B','C','D'])
print(df)
'''
A B C D
2018-09-30 0 1 2 3
2018-10-01 4 5 6 7
2018-10-02 8 9 10 11
2018-10-03 12 13 14 15
2018-10-04 16 17 18 19
2018-10-05 20 21 22 23
'''
#根据标签loc
print(df.loc['20181001'])
'''
A 4
B 5
C 6
D 7
Name: 2018-10-01 00:00:00, dtype: int32
'''
print(df.loc[:,['A','B']])
'''
A B
2018-09-30 0 1
2018-10-01 4 5
2018-10-02 8 9
2018-10-03 12 13
2018-10-04 16 17
2018-10-05 20 21
'''
print(df.loc['20181001',['A','B']])
'''
A 4
B 5
Name: 2018-10-01 00:00:00, dtype: int32
'''
3.根据序列iloc(用位置选择)
另外我们可以采用位置进行选择 iloc, 在这里我们可以通过位置选择在不同情况下所需要的数据例如选某一个,连续选或者跨行选等操作。
import numpy as np
import pandas as pd
dates=pd.date_range('20180930',periods=6)
df=pd.DataFrame(np.arange(24).reshape(6,4),index=dates,columns=['A','B','C','D'])
print(df)
#根据iloc
print(df.iloc[3,1])
#13
print(df.iloc[[1,3,5],1:3])
'''
B C
2018-10-01 5 6
2018-10-03 13 14
2018-10-05 21 22
'''
4.既可以根据位置也可以根据标签ix
print(df.ix[:3,['A','C']])
'''
A C
2018-09-30 0 2
2018-10-01 4 6
2018-10-02 8 10
'''
5.通过判断筛选
最后我们可以采用判断指令 (Boolean indexing) 进行选择. 我们可以约束某项条件然后选择出当前所有数据.
print(df[df.A>8])
'''
A B C D
2018-10-03 12 13 14 15
2018-10-04 16 17 18 19
2018-10-05 20 21 22 23
'''
三.Pandas设置值
- 根据位置设置loc和iloc
- 根据条件设置
- 按行或者按列设置
- 添加数据
import numpy as np
import pandas as pd
dates=pd.date_range('20181001',periods=6)
df=pd.DataFrame(np.arange(24).reshape(6,4),index=dates,columns=['A','B','C','D'])
print(df)
'''
A B C D
2018-10-01 0 1 2 3
2018-10-02 4 5 6 7
2018-10-03 8 9 10 11
2018-10-04 12 13 14 15
2018-10-05 16 17 18 19
2018-10-06 20 21 22 23
'''
#1.根据位置设置loc和iloc
df.iloc[2,2]=1111
df.loc['20181001','B']=2222
print(df)
'''
A B C D
2018-10-01 0 2222 2 3
2018-10-02 4 5 6 7
2018-10-03 8 9 1111 11
2018-10-04 12 13 14 15
2018-10-05 16 17 18 19
2018-10-06 20 21 22 23
'''
#2.根据条件设置
'''
判断条件是这样, 我们想要更改B中的数, 而更改的位置是取决于 A 的. 对于A大于4的位置. 更改B在相应位置上的数为0.
'''
df.B[df.A>4]=0
print(df)
'''
A B C D
2018-10-01 0 2222 2 3
2018-10-02 4 5 6 7
2018-10-03 8 0 1111 11
2018-10-04 12 0 14 15
2018-10-05 16 0 18 19
2018-10-06 20 0 22 23
'''
#3.按行或列设置
df['F']=np.nan
print(df)
'''
A B C D F
2018-10-01 0 2222 2 3 NaN
2018-10-02 4 5 6 7 NaN
2018-10-03 8 0 1111 11 NaN
2018-10-04 12 0 14 15 NaN
2018-10-05 16 0 18 19 NaN
2018-10-06 20 0 22 23 NaN
'''
#4.添加数据
df['E']=pd.Series([1,2,3,4,5,6],index=pd.date_range('20181001',periods=6))#必须把后面序号加上,不然后面的数字没法补上。
print(df)
四.Pandas处理丢失数据
pd.dropna():如果想直接去掉有 NaN 的行或列, 可以使用 dropna
pd.fillna():如果是将 NaN 的值用其他值代替, 比如代替成 0
pd.isnull():判断是否有缺失数据 NaN, 为 True 表示缺失数据
import numpy as np
import pandas as pd
dates=pd.date_range('20181001',periods=6)
df=pd.DataFrame(np.arange(24).reshape(6,4),index=dates,columns=['A','B','C','D'])
df.iloc[0,1]=np.nan
df.iloc[1,2]=np.nan
'''
A B C D
2018-10-01 0 NaN 2.0 3
2018-10-02 4 5.0 NaN 7
2018-10-03 8 9.0 10.0 11
2018-10-04 12 13.0 14.0 15
2018-10-05 16 17.0 18.0 19
2018-10-06 20 21.0 22.0 23
'''
#1.去除有NaN的行或列
print(df.dropna(axis=0,how='any'))
# 0: 对行进行操作; 1: 对列进行操作
# 'any': 只要存在 NaN 就 drop 掉; 'all': 必须全部是 NaN 才 drop
'''
A B C D
2018-10-03 8 9.0 10.0 11
2018-10-04 12 13.0 14.0 15
2018-10-05 16 17.0 18.0 19
2018-10-06 20 21.0 22.0 23
'''
#2.将NaN的值用其他值代替,比如代替成0
print(df.fillna(value=0))
'''
A B C D
2018-10-01 0 0.0 2.0 3
2018-10-02 4 5.0 0.0 7
2018-10-03 8 9.0 10.0 11
2018-10-04 12 13.0 14.0 15
2018-10-05 16 17.0 18.0 19
2018-10-06 20 21.0 22.0 23
'''
#3.判断是否有缺失数据,为True就是含有缺失数据
print(np.any(df.isnull()==True))
#True
五.Pandas导入导出
pandas可以读取与存取的资料格式有很多种,像csv、excel、json、html与pickle等…,且读取出的数据也会自动标上序号,这点很好。
- 读取csv
- 把资料存成pickle
import pandas as pd
data=pd.read_csv('G:\\NetWork\\TextRank\\data\\data.csv')
print(data)
data.to_pickle('G:\\NetWork\\TextRank\\data\\test.pickle')
六.Pandas合并concat
- axis控制合并方向
- ignore_index:重置index值
- join='outer'/'inner':未定义时默认为前者,outer:此方式是依照column来做纵向合并,有相同的column上下合并在一起,其他独自的column个自成列,原本没有值的位置皆以NaN填充。inner:只有相同的column合并在一起,其他的会被抛弃。可以简要的记着一点默认都是会保存所有值,只可能增加无效值不可能减少原有值。
- join_axes:按照axes合并,按照指定表格的序号合并,默认的话所有值都会有,用了这个属性与参照序号不同的合并项会被丢弃
- appen:添加数据
import pandas as pd
import numpy as np
df1 = pd.DataFrame(np.ones((3,4))*0, columns=['a','b','c','d'])
df2 = pd.DataFrame(np.ones((3,4))*1, columns=['a','b','c','d'])
df3 = pd.DataFrame(np.ones((3,4))*2, columns=['a','b','c','d'])
s1=pd.Series([1,2,3,4],index=['a','b','c','d'])
#1.concat纵向合并
res=pd.concat([df1,df2,df3],axis=0)
print(res)
'''
a b c d
0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
0 1.0 1.0 1.0 1.0
1 1.0 1.0 1.0 1.0
2 1.0 1.0 1.0 1.0
0 2.0 2.0 2.0 2.0
1 2.0 2.0 2.0 2.0
2 2.0 2.0 2.0 2.0
'''
#2.重置index
res=pd.concat([df1,df2,df3],axis=0,ignore_index=True)#忽略之前的序号,重新排序
print(res)
'''
a b c d
0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 1.0 1.0 1.0 1.0
4 1.0 1.0 1.0 1.0
5 1.0 1.0 1.0 1.0
6 2.0 2.0 2.0 2.0
7 2.0 2.0 2.0 2.0
8 2.0 2.0 2.0 2.0
'''
#3.join(合并方式)
df1=pd.DataFrame(np.ones((3,4))*0,columns=['a','b','c','d'],index=[1,2,3]) #注意ones里面的数组要用括号!!
df2=pd.DataFrame(np.ones((3,4))*1,columns=['b','c','d','e'],index=[2,3,4])
res=pd.concat([df1,df2],axis=0,join='outer')
print(res)
'''
outer:未设定任何参数时,函数默认join='outer'。
此方式是依照column来做纵向合并,有相同的column上下合并在一起,
其他独自的column个自成列,原本没有值的位置皆以NaN填充。
a b c d e
1 0.0 0.0 0.0 0.0 NaN
2 0.0 0.0 0.0 0.0 NaN
3 0.0 0.0 0.0 0.0 NaN
2 NaN 1.0 1.0 1.0 1.0
3 NaN 1.0 1.0 1.0 1.0
4 NaN 1.0 1.0 1.0 1.0
'''
print(pd.concat([df1,df2],axis=0,join='inner'))
'''
inner:,但只有相同的column合并在一起,其他的会被抛弃。
b c d
1 0.0 0.0 0.0
2 0.0 0.0 0.0
3 0.0 0.0 0.0
2 1.0 1.0 1.0
3 1.0 1.0 1.0
4 1.0 1.0 1.0
'''
print(pd.concat([df1,df2],axis=0,join='inner',ignore_index=True))#重置index打印结果
'''
b c d
0 0.0 0.0 0.0
1 0.0 0.0 0.0
2 0.0 0.0 0.0
3 1.0 1.0 1.0
4 1.0 1.0 1.0
5 1.0 1.0 1.0
'''
#4.join_axes
print(pd.concat([df1,df2],axis=1))#按列拼凑
'''
a b c d b c d e
1 0.0 0.0 0.0 0.0 NaN NaN NaN NaN
2 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
3 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
4 NaN NaN NaN NaN 1.0 1.0 1.0 1.0
'''
print(pd.concat([df1, df2], axis=1, join_axes=[df1.index])) #按照df1的index值合并列
'''
a b c d b c d e
1 0.0 0.0 0.0 0.0 NaN NaN NaN NaN
2 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
3 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0
'''
#5.添加数据
df1 = pd.DataFrame(np.ones((3,4))*0, columns=['a','b','c','d'])
df2 = pd.DataFrame(np.ones((3,4))*1, columns=['a','b','c','d'])
print(df1.append(df2,ignore_index=True))
'''
a b c d
0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0
3 1.0 1.0 1.0 1.0
4 1.0 1.0 1.0 1.0
5 1.0 1.0 1.0 1.0
'''
七. Pandas合并merge
pandas中的merge和concat类似,但主要是用于两组有key column的数据,统一索引的数据. 通常也被用在Database的处理当中
- 依据一组key合并:res = pd.merge(left, right, on='key')
- 依据两组key合并:res = pd.merge(left, right, on=['key1', 'key2'], how='inner') ,合并时有4种方法how = ['left', 'right', 'outer', 'inner'],预设值how='inner'。
- Indicator:ndicator=True会将合并的记录放在新的一列
- 根据index合并:res = pd.merge(left, right, left_index=True, right_index=True, how='outer'),标红属性不可少
- 解决overlapping问题:res = pd.merge(boys, girls, on='k', suffixes=['_boy', '_girl'], how='inner'),使用suffixes解决属性冲突问题,并且可以给不同表的属性命名。
import pandas as pd
import numpy as np
#1.根据一组key合并
left=pd.DataFrame({
'key':['K0','K1','K2','K3'],
'A':['A0','A1','A2','A3'],
'B':['B0','B1','B2','B3']
}
)
right=pd.DataFrame({
'key':['K0','K1','K2','K3'],
'C':['C0','C1','C2','C3'],
'D':['D0','D1','D2','D3']
}
)
print(pd.merge(left,right,on='key'))
'''
A B key C D
0 A0 B0 K0 C0 D0
1 A1 B1 K1 C1 D1
2 A2 B2 K2 C2 D2
3 A3 B3 K3 C3 D3
'''
#2.依据2组key合并
#合并时有4种方法how = ['left', 'right', 'outer', 'inner'],预设值how='inner'
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
'key2': ['K0', 'K1', 'K0', 'K1'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
'key2': ['K0', 'K0', 'K0', 'K0'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
print(left)
'''
A B key1 key2
0 A0 B0 K0 K0
1 A1 B1 K0 K1
2 A2 B2 K1 K0
3 A3 B3 K2 K1
'''
print(right)
'''
C D key1 key2
0 C0 D0 K0 K0
1 C1 D1 K1 K0
2 C2 D2 K1 K0
3 C3 D3 K2 K0
'''
print(pd.merge(left,right,on=['key1','key2'],how='inner'))#只把key1,key2相同数列合并
'''
A B key1 key2 C D
0 A0 B0 K0 K0 C0 D0
1 A2 B2 K1 K0 C1 D1
2 A2 B2 K1 K0 C2 D2
'''
print(pd.merge(left,right,on=['key1','key2'],how='outer'))#把两个表格的所有key1,key2都合并在一起
'''
A B key1 key2 C D
0 A0 B0 K0 K0 C0 D0
1 A1 B1 K0 K1 NaN NaN
2 A2 B2 K1 K0 C1 D1
3 A2 B2 K1 K0 C2 D2
4 A3 B3 K2 K1 NaN NaN
5 NaN NaN K2 K0 C3 D3
'''
print(pd.merge(left,right,on=['key1','key2'],how='left'))#以左边表格的key1,key2组合为基准,如果右边数组有就合并,没有就补NaN
'''
A B key1 key2 C D
0 A0 B0 K0 K0 C0 D0
1 A1 B1 K0 K1 NaN NaN
2 A2 B2 K1 K0 C1 D1
3 A2 B2 K1 K0 C2 D2
4 A3 B3 K2 K1 NaN NaN
'''
print(pd.merge(left,right,on=['key1','key2'],how='right'))#以右边表格的key1,key2组合为基准,如果左边数组有就合并,没有就补NaN
'''
A B key1 key2 C D
0 A0 B0 K0 K0 C0 D0
1 A2 B2 K1 K0 C1 D1
2 A2 B2 K1 K0 C2 D2
3 NaN NaN K2 K0 C3 D3
'''
#3.Indicator,将合并的记录放在新的一列
df1 = pd.DataFrame({'col1':[0,1], 'col_left':['a','b']})
df2 = pd.DataFrame({'col1':[1,2,2],'col_right':[2,2,2]})
# 依据col1进行合并,并启用indicator=True,最后打印出
print(pd.merge(df1, df2, on='col1', how='outer', indicator=True))
'''
col1 col_left col_right _merge
0 0 a NaN left_only
1 1 b 2.0 both
2 2 NaN 2.0 right_only
3 2 NaN 2.0 right_only
'''
# 自定indicator column的名称,并打印出
print(pd.merge(df1, df2, on='col1', how='outer', indicator='indicator_column'))
'''
col1 col_left col_right indicator_column
0 0 a NaN left_only
1 1 b 2.0 both
2 2 NaN 2.0 right_only
3 2 NaN 2.0 right_only
'''
#4.根据index合并
left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
'B': ['B0', 'B1', 'B2']},
index=['K0', 'K1', 'K2'])
right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
'D': ['D0', 'D2', 'D3']},
index=['K0', 'K2', 'K3'])
#依据左右资料集的index进行合并,how='outer',并打印出
print(pd.merge(left, right, left_index=True, right_index=True, how='outer'))#这个left_index和right_index参数必须有
print(pd.merge(left, right, left_index=True, right_index=True, how='outer'))
#依据左右资料集的index进行合并,how='inner',并打印出
print(pd.merge(left, right, left_index=True, right_index=True, how='inner'))
#5.解决overlapping问题
#定义资料集
boys = pd.DataFrame({'k': ['K0', 'K1', 'K2'], 'age': [1, 2, 3]})
girls = pd.DataFrame({'k': ['K0', 'K0', 'K3'], 'age': [4, 5, 6]})
#使用suffixes解决overlapping的问题
res = pd.merge(boys, girls, on='k', suffixes=['_boy', '_girl'], how='inner')
print(res)
八.Pandas plot出图
- 创建一个Series,熟悉 matplotlib 的朋友知道如果需要plot一个数据,我们可以使用 plt.plot(x=, y=),把x,y的数据作为参数存进去,但是data本来就是一个数据,所以我们可以直接plot。
- Dataframe可视化
- Scater用法(散点图)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#随机生成1000个数据
data=pd.Series(np.random.randn(1000),index=np.arange(1000))
#为了方便观看数据,累加数据
data.cumsum
'''
plt.plot(x=,y=),但是data本来就是一个数据,可以直接plot
'''
data.plot()
plt.show()
data=pd.DataFrame(
np.random.randn(1000,4),
index=np.arange(1000),
columns=list('ABCD')
)
data.cumsum()
data.plot()
plt.show()
ax = data.plot.scatter(x='A',y='B',color='DarkBlue',label='Class1')
data.plot.scatter(x='A',y='C',color='LightGreen',label='Class2',ax=ax)
plt.show()