Pandas库学习
- 相较于numpy库关注数据结构的表达,pandas库更关注数据的应用表达
1.Pandas库的Series类型
1.1 Series类型的组成
Series类型由一组数据及与之相关的数据索引组成
自动索引
自定义索引
1.2 Series类型的创建
从标量值创建
In[1]: import pandas as pd
In[2]: s = pd.Series(25,index=['a','b','c'])
In[3]: s
Out[3]:
a 25
b 25
c 25
dtype: int64
从字典类型创建
In[1]: import pandas as pd
In[2]: d = pd.Series({'a':9,'b':8,'c':7})
In[3]: d
Out[3]:
a 9
b 8
c 7
dtype: int64
从ndarray类型创建
In[1]: import numpy as np
In[2]: import pands as pd
In[3]: n = pd.Series(np.arange(5))
In[4]: n
Out[4]:
0 0
1 1
2 2
3 3
4 4
dtype: int32
1.3 Series类型的操作
(1) 自动索引和自定义索引并存,但不能混用
(2) Series类型的操作类似ndarray类型
- 索引方法相同,采用[]
- Numpy中运算和操作可用于Series类型
- 可以通过自定义索引的列表进行切片
- 可以通过自动索引进行切片,如果存在自定义索引,则一同被切片
(3) Series类型的操作类似Python字典类型
- 通过自定义索引访问
- 保留字in操作
- 使用.get()方法
In[1]: import pandas as pd
In[2]: b = pd.Series([9,8,7,6],['a','b','c','d'])
In[3]: b['b']
Out[3]: 8
In[4]: 'c' in b
Out[4]: True
In[5]: 0 in b
Out[5]: False
In[6]: b.get('f',100)
Out[6]: 100
(4) Series类型对齐操作
Series类型在运算中会自动对齐不同索引的数据
In[1]: a = pd.Series([1,2,3],['c','d','e'])
In[2]: b = pd.Series([9,8,7,6],['a','b','c','d'])
In[3]: a + b
Out[3]:
a NaN
b NaN
c 8.0
d 8.0
e NaN
dtype: float64
(5) Series类型的name属性
Series对象和索引都可以有一个名字,存储在属性.name中
In[1]: import pandas as pd
In[2]: b = pd.Series([9,8,7,6],['a','b','c','d'])
In[3]: b.name
In[4]: b.name = "series对象"
In[5]: b.index.name = '索引列'
In[6]: b
Out[6]:
索引列
a 9
b 8
c 7
d 6
Name: series对象, dtype: int64
(6)Series类型的修改
Series对象可以随时修改并即刻生效
In[1]: import pandas as pd
In[2]: b = pd.Series([9,8,7,6],['a','b','c','d'])
In[3]: b['a'] = 15
In[4]: b.name = "Series"
In[5]: b
Out[5]:
索引列
a 15
b 8
c 7
d 6
Name: Series, dtype: int64
1.4 Series类型的总结
- Series是一维带“标签”的数组
- Series基本操作类似ndarray和字典,根据索引对齐
2.Pandas库的DataFrame类型
2.1 DataFrame类型组成
DataFrame类型由共用相同索引的一组列组成
- DataFrame是一个表格型的数据类型,每列值类型可以不同
- DataFrame既有行索引、也有列索引
- DataFrame常用于表达二维数据,但可以表达多维数据
2.2 DataFrame类型的创建
- 二维ndarray对象
- 由一维ndarray、列表、字典、元组或Series构成的字典
- Series类型
- 其他的DataFrame类型
(1) 从二维ndarray对象创建
In[1]: import pandas as pd
In[2]: import numpy as np
In[3]: d = pd.DataFrame(np.arange(10).reshape(2,5))
In[4]: d
Out[4]:
0 1 2 3 4
0 0 1 2 3 4
1 5 6 7 8 9
(2) 从一维ndarray对象字典创建
In[1]: import pandas as pd
In[2]: dt = {'one':pd.Series([1,2,3],index = ['a','b','c']),'two':pd.Series([9,8,7,6],index = ['a','b','c','d'])}
In[3]: d = pd.DataFrame(dt)
In[4]: d
Out[4]:
one two
a 1.0 9
b 2.0 8
c 3.0 7
d NaN 6
In[5]: pd.DataFrame(dt,index = ['b','c','d'],columns= ['two','three'])
Out[5]:
two three
b 8 NaN
c 7 NaN
d 6 NaN
(3) 从列表类型的字典来创建
In[1]: import pandas as pd
In[2]: dl = {'one':[1,2,3,4],'two':[9,8,7,6]}
In[3]: d = pd.DataFrame(dl,index= ['a','b','c','d'])
In[4]: d
Out[4]:
one two
a 1 9
b 2 8
c 3 7
d 4 6
2.3 DataFrame类型元素获取
- 获取某一列的数据
df[column]
- 获取某一行的数据
df.loc[index]
- 获取某一行某一列的数据
df[column][index]
In[1] :import pandas as pd
In[2]: dl = {'城市':['北京','上海','广州','深圳','沈阳'],
'环比': [101.5,101.2,101.3,102.0,100.1],
'同比': [120.7,127.3,119.4,140.9,101.4],
'定基': [121.4,127.8,120.0,145.5,101.6]}
In[3]: d = pd.DataFrame(dl,index = ['c1','c2','c3','c4','c5'])
In[4]:d
out[4]:
城市 环比 同比 定基
c1 北京 101.5 120.7 121.4
c2 上海 101.2 127.3 127.8
c3 广州 101.3 119.4 120.0
c4 深圳 102.0 140.9 145.5
c5 沈阳 100.1 101.4 101.6
In[5]: d['同比']
out[5]:
c1 120.7
c2 127.3
c3 119.4
c4 140.9
c5 101.4
Name: 同比, dtype: float64
In[6]: d.loc['c2']
out[6]:
城市 上海
环比 101.2
同比 127.3
定基 127.8
Name: c2, dtype: object
In[7]:d['同比']['c2']
out[7]: 127.3
3.Pandas库的数据类型操作
3.1 重新索引
.reindex()
能够改变或者重排Series和DataFrame索引
In[1] :import pandas as pd
In[2]: dl = {'城市':['北京','上海','广州','深圳','沈阳'],
'环比': [101.5,101.2,101.3,102.0,100.1],
'同比': [120.7,127.3,119.4,140.9,101.4],
'定基': [121.4,127.8,120.0,145.5,101.6]}
In[3]: d = pd.DataFrame(dl,index = ['c1','c2','c3','c4','c5'])
In[4]: d = d.reindex(index = ['c5','c4','c3','c2','c1'])
In[5]: d
out[5]:
城市 环比 同比 定基
c5 沈阳 100.1 101.4 101.6
c4 深圳 102.0 140.9 145.5
c3 广州 101.3 119.4 120.0
c2 上海 101.2 127.3 127.8
c1 北京 101.5 120.7 121.4
In[6]: newc = d.columns.insert(4,'新增')
In[7]: newc
out[7]:Index(['城市', '环比', '同比', '定基', '新增'], dtype='object')
In[8]: newd = d.reindex(columns = newc,fill_value = 200)
In[9]: newd
out[9]:
城市 环比 同比 定基 新增
c5 沈阳 100.1 101.4 101.6 200
c4 深圳 102.0 140.9 145.5 200
c3 广州 101.3 119.4 120.0 200
c2 上海 101.2 127.3 127.8 200
c1 北京 101.5 120.7 121.4 200
3.2 索引修改
- Series和DataFrame的索引是Index类型,Index对象是不可修改的类型
- 索引必须单调递增或者单调递减
In[1]: nc = d.columns.delete(2)
In[2]: ni = d.index.insert(5,'c0')
In[3]: nd = d.reindex(index = ni,columns = nc,method = 'ffill')
注意:在上述第三行代码中,删除导致索引不单调了,所以同步使用method来填充的时候就会出错
这里我们将第三行代码改为先进行删除,再调用.ffill()或.bfill()
In[4]: nd = d.reindex(index = ni,columns = nc).ffill()
In[5]: nd
out[5]:
城市 环比 定基
c5 沈阳 100.1 101.6
c4 深圳 102.0 145.5
c3 广州 101.3 120.0
c2 上海 101.2 127.8
c1 北京 101.5 121.4
c0 北京 101.5 121.4
3.3 索引删除
.drop
能够删除Series和DataFrame指定行或列索引
- 对于Series类型
In[1]: a = pd.Series([9,8,7,6],index = ['a','b','c','d'])
In[2]:a
out[2]:
a 9
b 8
c 7
d 6
dtype: int64
In[3]:a.drop(['b','c'])
out[3]:
a 9
d 6
dtype: int64
- 对于DataFrame类型(注意在删除列的时候,给出axis=1)
In[1]:d
out[1]:
城市 环比 同比 定基
c5 沈阳 100.1 101.4 101.6
c4 深圳 102.0 140.9 145.5
c3 广州 101.3 119.4 120.0
c2 上海 101.2 127.3 127.8
c1 北京 101.5 120.7 121.4
In[2]: d.drop('c5')
out[2]:
城市 环比 同比 定基
c4 深圳 102.0 140.9 145.5
c3 广州 101.3 119.4 120.0
c2 上海 101.2 127.3 127.8
c1 北京 101.5 120.7 121.4
In[3]: d.drop('同比',axis = 1)
out[3]:
城市 环比 定基
c5 沈阳 100.1 101.6
c4 深圳 102.0 145.5
c3 广州 101.3 120.0
c2 上海 101.2 127.8
c1 北京 101.5 121.4
4. Pandas库的数据类型运算
4.1 算术运算法则
- 算术运算根据行列索引,补齐后运算,运算默认产生浮点数
- 补齐时缺项填充NaN(空值)
- 二维和一维、一维和零维为广播运算
- 采用+-*/符号进行的二元运算产生新的对象
符号形式的运算
In[1]:import pandas as pd
In[2]:import numpy as np
In[3]:a = pd.DataFrame(np.arange(12).reshape(3, 4))
In[4]:a
out[4]:
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
In[5]:b = pd.DataFrame(np.arange(20).reshape(4, 5))
In[6]:b
Out[6]:
0 1 2 3 4
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19
In[7]:a + b
out[7]:
0 1 2 3 4
0 0.0 2.0 4.0 6.0 NaN
1 9.0 11.0 13.0 15.0 NaN
2 18.0 20.0 22.0 24.0 NaN
3 NaN NaN NaN NaN NaN
In[8]:a*b
out[8]:
0 1 2 3 4
0 0.0 1.0 4.0 9.0 NaN
1 20.0 30.0 42.0 56.0 NaN
2 80.0 99.0 120.0 143.0 NaN
3 NaN NaN NaN NaN NaN
方法形式的运算
In[9]: b.add(a,fill_value=100)
Out[9]:
0 1 2 3 4
0 0.0 2.0 4.0 6.0 104.0
1 9.0 11.0 13.0 15.0 109.0
2 18.0 20.0 22.0 24.0 114.0
3 115.0 116.0 117.0 118.0 119.0
In[10]: a.mul(b,fill_value=0)
out[10]:
0 1 2 3 4
0 0.0 1.0 4.0 9.0 0.0
1 20.0 30.0 42.0 56.0 0.0
2 80.0 99.0 120.0 143.0 0.0
3 0.0 0.0 0.0 0.0 0.0
不同维度间的运算
不同维度间为广播运算,一维Series默认在轴1(行)参与运算
In[1]:b = pd.DataFrame(np.arange(20).reshape(4, 5))
In[2]:b
out[2]:
0 1 2 3 4
0 0 1 2 3 4
1 5 6 7 8 9
2 10 11 12 13 14
3 15 16 17 18 19
In[3]: c = pd.Series(np.arange(4))
In[4]: c
out[4]:
0 0
1 1
2 2
3 3
In[5]:c - 10
Out[16]:
0 -10
1 -9
2 -8
3 -7
dtype: int32
# b的每一行与c进行相减
In[6]: b - c
Out[17]:
0 1 2 3 4
0 0.0 0.0 0.0 0.0 NaN
1 5.0 5.0 5.0 5.0 NaN
2 10.0 10.0 10.0 10.0 NaN
3 15.0 15.0 15.0 15.0 NaN
使用运算方法可以令一维Series参与轴0运算
In[7]: b.sub(c,axis=0)
Out[7]:
0 1 2 3 4
0 0 1 2 3 4
1 4 5 6 7 8
2 8 9 10 11 12
3 12 13 14 15 16
4.2 比较运算法则
- 比较运算只能比较相同索引的元素,不进行补齐
- 二维和一维、一维和零维间为广播运算
- 采用> < >= <= == !=等符号进行的二元运算产生布尔对象
不同维度,广播运算,默认在1轴
In[1]:import pandas as pd
In[2]:import numpy as np
In[3]:a = pd.DataFrame(np.arange(12).reshape(3, 4))
In[4]:a
out[4]:
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
In[5]: c = pd.Series(np.arange(4))
In[6]: c
out[6]:
0 0
1 1
2 2
3 3
In[7]: a > c
Out[7]:
0 1 2 3
0 False False False False
1 True True True True
2 True True True True
In[8]:c > 0
Out[8]:
0 False
1 True
2 True
3 True
dtype: bool
5.Pandas库的数据分析
5.1 数据排序
- 对于索引排序
.sort_index(axis=0,ascending=True)
方法在指定轴上根据索引进行排序,默认升序
In[1]: import pandas as pd
In[2]: import numpy as np
In[3]: b = pd.DataFrame(np.arange(20).reshape(4,5),index = ['c','a','d','b'])
In[4]: b
Out[4]:
0 1 2 3 4
c 0 1 2 3 4
a 5 6 7 8 9
d 10 11 12 13 14
b 15 16 17 18 19
In[5]: b.sort_index()
Out[5]:
0 1 2 3 4
a 5 6 7 8 9
b 15 16 17 18 19
c 0 1 2 3 4
d 10 11 12 13 14
In[6]: b.sort_index(ascending = False)
Out[6]:
0 1 2 3 4
d 10 11 12 13 14
c 0 1 2 3 4
b 15 16 17 18 19
a 5 6 7 8 9
- 对于数值排序
Series.sort_values(axis=0,ascending=True)
DataFrame.sort_values(by,axis=0,ascending=True)
其中by: axis轴上的某个索引或者索引列表
In[1]: b = pd.DataFrame(np.arange(20).reshape(4,5),index = ['c','a','d','b'])
In[2]: b
Out[2]:
0 1 2 3 4
c 0 1 2 3 4
a 5 6 7 8 9
d 10 11 12 13 14
b 15 16 17 18 19
In[3]:c = b.sort_values(2,ascending = False)
In[4]:c
Out[4]:
0 1 2 3 4
b 15 16 17 18 19
d 10 11 12 13 14
a 5 6 7 8 9
c 0 1 2 3 4
In[5]: c = c.sort_values('a',axis=1,ascending=False)
In[6]: c
Out[6]:
4 3 2 1 0
b 19 18 17 16 15
d 14 13 12 11 10
a 9 8 7 6 5
c 4 3 2 1 0
- 对于空值NaN统一放到排序末尾
In[3]:import numpy as np
a = pd.DataFrame(np.arange(12).reshape(3,4),index =['a','b','c'] )
a
Out[5]:
0 1 2 3
a 0 1 2 3
b 4 5 6 7
c 8 9 10 11
b = pd.DataFrame(np.arange(20).reshape(4,5),index= ['c','a','d','b'])
b
Out[7]:
0 1 2 3 4
c 0 1 2 3 4
a 5 6 7 8 9
d 10 11 12 13 14
b 15 16 17 18 19
c = a + b
c
Out[9]:
0 1 2 3 4
a 5.0 7.0 9.0 11.0 NaN
b 19.0 21.0 23.0 25.0 NaN
c 8.0 10.0 12.0 14.0 NaN
d NaN NaN NaN NaN NaN
c.sort_values(2,ascending = False)
Out[10]:
0 1 2 3 4
b 19.0 21.0 23.0 25.0 NaN
c 8.0 10.0 12.0 14.0 NaN
a 5.0 7.0 9.0 11.0 NaN
d NaN NaN NaN NaN NaN
c.sort_values(2,ascending = True)
Out[11]:
0 1 2 3 4
a 5.0 7.0 9.0 11.0 NaN
c 8.0 10.0 12.0 14.0 NaN
b 19.0 21.0 23.0 25.0 NaN
d NaN NaN NaN NaN NaN
5.2 数据的基本统计排序
- 适用于Series和DataFrame类型
In[1]: import pandas as pd
In[2]: a = pd.Series([9,8,7,6],index =['a','b','c','d'])
In[3]: a
Out[3]:
a 9
b 8
c 7
d 6
dtype: int64
In[4]: a.describe()
Out[4]:
count 4.000000
mean 7.500000
std 1.290994
min 6.000000
25% 6.750000
50% 7.500000
75% 8.250000
max 9.000000
dtype: float64
In[5]: type(a.describe())
Out[5]: pandas.core.series.Series
In[6]: a.describe()['count']
Out[6]: 4.0
In[7]: a.describe()['max']
Out[7]: 9.0
In[8]: b = pd.DataFrame(np.arange(20).reshape(4,5),index = ['c','a','d','b'])
In[9]: b.describe()
Out[9]:
0 1 2 3 4
count 4.000000 4.000000 4.000000 4.000000 4.000000
mean 7.500000 8.500000 9.500000 10.500000 11.500000
std 6.454972 6.454972 6.454972 6.454972 6.454972
min 0.000000 1.000000 2.000000 3.000000 4.000000
25% 3.750000 4.750000 5.750000 6.750000 7.750000
50% 7.500000 8.500000 9.500000 10.500000 11.500000
75% 11.250000 12.250000 13.250000 14.250000 15.250000
max 15.000000 16.000000 17.000000 18.000000 19.000000
In[10]: type(b.describe())
Out[10]: pandas.core.frame.DataFrame
In[11]: b.describe().loc['count']
Out[11]:
0 4.0
1 4.0
2 4.0
3 4.0
4 4.0
Name: count, dtype: float64
In[12]: b.describe()[1]
Out[12]:
count 4.000000
mean 8.500000
std 6.454972
min 1.000000
25% 4.750000
50% 8.500000
75% 12.250000
- 适用于Series类型
5.3 数据的累计统计分析
In[1]: b
Out[1]:
0 1 2 3 4
c 0 1 2 3 4
a 5 6 7 8 9
d 10 11 12 13 14
b 15 16 17 18 19
In[2]: b.cumsum()
Out[2]:
0 1 2 3 4
c 0 1 2 3 4
a 5 7 9 11 13
d 15 18 21 24 27
b 30 34 38 42 46
In[3]:b.cumprod()
Out[3]:
0 1 2 3 4
c 0 1 2 3 4
a 0 6 14 24 36
d 0 66 168 312 504
b 0 1056 2856 5616 9576
In[4]:b.cummin()
Out[4]:
0 1 2 3 4
c 0 1 2 3 4
a 0 1 2 3 4
d 0 1 2 3 4
b 0 1 2 3 4
In[5]: b.cummax()
Out[5]:
0 1 2 3 4
c 0 1 2 3 4
a 5 6 7 8 9
d 10 11 12 13 14
b 15 16 17 18 19
- 滚动计算(窗口计算)
In[1]: b
Out[1]:
0 1 2 3 4
c 0 1 2 3 4
a 5 6 7 8 9
d 10 11 12 13 14
b 15 16 17 18 19
In[2]: b.rolling(2).sum()
Out[2]:
0 1 2 3 4
c NaN NaN NaN NaN NaN
a 5.0 7.0 9.0 11.0 13.0
d 15.0 17.0 19.0 21.0 23.0
b 25.0 27.0 29.0 31.0 33.0
In[3]: b.rolling(3).sum()
Out[3]:
0 1 2 3 4
c NaN NaN NaN NaN NaN
a NaN NaN NaN NaN NaN
d 15.0 18.0 21.0 24.0 27.0
b 30.0 33.0 36.0 39.0 42.0
5.4 数据的相关分析
两个事物,表示为X和Y的相关性:
- X增大,Y增大,两个变量正相关
- X增大,Y减小,两个变量负相关
- X增大,Y无视,两个变量不相关
协方差:
- 协方差>0,X和Y正相关
- 协方差<0,X和Y负相关
- 协方差=0,X和Y独立无关
Pearson相关系数:
- 0.8-1.0 极强相关
- 0.6-0.8 强相关
- 0.4-0.6 中等程度相关
- 0.2-0.4 弱相关
- 0.0-0.2 极弱相关或无相关
相关分析函数:
实例:房价增幅与M2增幅的相关性
import pandas as pd
import matplotlib.pyplot as plt
# 消除FutureWarning
from warnings import simplefilter
simplefilter(action="ignore", category=FutureWarning)
# 设置显示中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
hprice = pd.Series([3.04, 22.93, 12.75, 22.6, 12.33], index=['2008', '2009', '2010', '2011', '2012'])
m2 = pd.Series([8.18, 18.38, 9.13, 7.82, 6.69], index=['2008', '2009', '2010', '2011', '2012'])
# 相关系数
cor = hprice.corr(m2)
print(cor)
# 画出房价和M2的图像
hprice.plot(kind='line', c='b',label = '房价')
m2.plot.line(c='y',label = 'M2')
plt.legend(loc = 'best')
plt.show()