Loading

Python之Pandas库学习(一):简介

官方文档

1. 安装Pandas

windos下cmd:pip install pandas

导入pandas包:import pandas as pd

2. Series对象

带索引的一维数组

创建:
s = pd.Series([12,-4,7,9])
print (s)
0    12
1    -4
2     7
3     9
dtype: int64

s = pd.Series([12,-4,7,9], index = ['a', 'b', 'c', 'd'])
print (s)
a    12
b    -4
c     7
d     9
dtype: int64

查看元素
print(s.values)
[12 -4  7  9]

查看索引标签
print(s.index)
Index(['a', 'b', 'c', 'd'], dtype='object')

使用NumPy数组定义Series对象
>>> arr = np.array([1,2,3,4])
>>> s3 = pd.Series(arr)
>>> s3
0    1
1    2
2    3
3    4
dtype: int32

使用Series对象也可以定义NumPy数组
>>> arr = np.array(s)
>>> arr
array([12, -4,  7,  9], dtype=int64)

Series对象当做字典
>>> dict = {'red':200, 'blue':20, 'orange':10}
>>> s = pd.Series(dict)
>>> s
blue       20
orange     10
red       200
dtype: int64
>>> dict
{'red': 200, 'orange': 10, 'blue': 20}

在上例的基础上
>>> dict = {'red':100, 'blue':30, 'black':50}
>>> ss = pd.Series(dict)
>>> ss + s
black       NaN
blue       50.0
orange      NaN
red       300.0
dtype: float64
>>> ss - s
black       NaN
blue       10.0
orange      NaN
red      -100.0
dtype: float64
说明Series对象相运算都是取索引的标签的交集进行运算,没有交集的值为NaN

2. DataFrame对象

类似于Excel表。设计初衷是将Series由一维拓展到多维。

2.1. 定义

>>> data = {'color' : ['blue','green','yellow','red','white'],
... 'object' : ['ball','pen','pencil','paper','mug'],
... 'price' : [1.2,1.0,0.6,0.9,1.7]}
>>> frame = pd.DataFrame(data)
>>> frame
    color  object  price
0    blue    ball    1.2
1   green     pen    1.0
2  yellow  pencil    0.6
3     red   paper    0.9
4   white     mug    1.7

可以只创建部分的列
>>> frame2 = pd.DataFrame(data, columns=['object','price'])
>>> frame2
   object  price
0    ball    1.2
1     pen    1.0
2  pencil    0.6
3   paper    0.9
4     mug    1.7

和Series一样可以指明索引的标签
>>> frame3 = pd.DataFrame(data, index = ['a', 'b', 'c', 'd', 'e'])
>>> frame3
    color  object  price
a    blue    ball    1.2
b   green     pen    1.0
c  yellow  pencil    0.6
d     red   paper    0.9
e   white     mug    1.7

使用np.array快速创建
>>> frame4 = pd.DataFrame(np.arange(16).reshape((4,4)), index = ['red', 'blue', 'yellow', 'white'], columns = ['ball', 'pen', 'pencil', 'paper'])
>>> frame4
        ball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15

使用嵌套字典创建(可以看出列是一级字典的键值,索引标签是二级字典的键值)
>>> dict = {'red' : {1000: 1, 2000: 2}, 'blue' : {3000: 3, 4000: 4}, 'orange' : {1000: 10, 3000: 30}}
>>> frame = pd.DataFrame(dict)
>>> frame
      blue  orange  red
1000   NaN    10.0  1.0
2000   NaN     NaN  2.0
3000   3.0    30.0  NaN
4000   4.0     NaN  NaN

2.2. 选取元素

和Series类似,多了一个查看列名
>>> frame4.columns
Index(['ball', 'pen', 'pencil', 'paper'], dtype='object')
>>> frame4.index
Index(['red', 'blue', 'yellow', 'white'], dtype='object')
>>> frame4.values
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
       
查看列信息
>>> frame4['pencil']
red        2
blue       6
yellow    10
white     14
Name: pencil, dtype: int32

查看行信息
>>> frame4.ix[2]
ball       8
pen        9
pencil    10
paper     11
Name: yellow, dtype: int32

同时可以使用切片来查询行信息
>>> frame4[1:3]
        ball  pen  pencil  paper
blue       4    5       6      7
yellow     8    9      10     11

查找具体的元素,用索引和用索引的标签都是一样的(这里应该先用列再用行..本来都是习惯先行再列的)
>>> frame4['pencil'][1]
6
>>> frame4['pencil']['blue']
6

2.3. 赋值和删除

给index和columns设置标签
>>> frame4.index.name = '茵蒂克丝'(我只是个魔禁粉)
>>> frame4.columns.name = '考拉能丝'(为了协调)
>>> frame4
考拉能丝    ball  pen  pencil  paper
茵蒂克丝                            
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15

添加新的列
>>> frame4['new'] = [101, 102, 103, 104]
>>> frame4
考拉能丝    ball  pen  pencil  paper  new
茵蒂克丝                                 
red        0    1       2      3  101
blue       4    5       6      7  102
yellow     8    9      10     11  103
white     12   13      14     15  104
>>> frame4['newnew'] = 1000
>>> frame4
考拉能丝    ball  pen  pencil  paper  new  newnew
茵蒂克丝                                         
red        0    1       2      3  101    1000
blue       4    5       6      7  102    1000
yellow     8    9      10     11  103    1000
white     12   13      14     15  104    1000

删除一列
>>> del frame4['new']
>>> frame4
考拉能丝    ball  pen  pencil  paper  newnew
茵蒂克丝                                    
red        0    1       2      3    1000
blue       4    5       6      7    1000
yellow     8    9      10     11    1000
white     12   13      14     15    1000

2.4. 转置

很强大,把列变成行,行变成列
>>> frame4.T
茵蒂克丝     red  blue  yellow  white
考拉能丝                             
ball       0     4       8     12
pen        1     5       9     13
pencil     2     6      10     14
paper      3     7      11     15
newnew  1000  1000    1000   1000

3. Index对象

3.1. Index的tips

索引是可以重复的
>>> s = pd.Series(range(6), index = ['white', 'blue', 'white', 'green', 'green', 'orange'])
>>> s
white     0
blue      1
white     2
green     3
green     4
orange    5
dtype: int32
一个标签对应多个元素,会得到一个Series对象。(DataFrame同理)
>>> s['green']
green    3
green    4
dtype: int32

3.2. Index的一些方法

返回索引值最大和最小的元素
>>> s.idxmax()
'orange'
>>> s.idxmin()
'white'

判断数据结构中是否存在重复的索引项
>>> s.index.is_unique
False

3.3. 更换索引

虽然数据结构一旦声明,Index对象不能改变,但是可以通过reindex方法改变索引标签。
>>> s = pd.Series([2,5,7,4], index = ['a', 'b', 'c', 'd'])
>>> s
a    2
b    5
c    7
d    4
dtype: int64
>>> s.reindex(['b', 'a', 'd', 'e'])
b    5.0
a    2.0
d    4.0
e    NaN
dtype: float64
这个例子可以看出,可以更换索引标签的顺序,新的标签会赋值为NaN。

自动完成索引
>>> s = pd.Series([1,5,6,3], index = [0,3,5,6])
>>> s
0    1
3    5
5    6
6    3
dtype: int64
>>> s.reindex(range(7), method = 'ffill')
0    1
1    1
2    1
3    5
4    5
5    6
6    3
dtype: int64
>>> s.reindex(range(7), method = 'bfill')
0    1
1    5
2    5
3    5
4    6
5    6
6    3
dtype: int64
range(7)代表索引的值为0~6,method代表填充的方式.
'ffill'是新插入的索引,其元素为索引编号比它小的那一项的元素,例如索引1就使用索引0的元素,索引2使用索引1的元素。
'bfill'是新插入的索引,其元素为索引编号比它大的那一项的元素。

3.4. 删除

使用drop()方法删除。
>>> s
0    1
3    5
5    6
6    3
dtype: int64
>>> s.drop(3)
0    1
5    6
6    3
dtype: int64
>>> s.drop([0,6])
3    5
5    6
dtype: int64

删除DataFrame中的元素,需要指定元素两个轴的轴标签。
>>> frame = pd.DataFrame(np.arange(16).reshape(4, 4), index = ['red', 'blue', 'yellow', 'white'], columns = ['ball', 'pen', 'pencil', 'paper'])
>>> frame
        ball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15
删除行只需要指明行的标签
>>> frame.drop(['blue', 'white'])
        ball  pen  pencil  paper
red        0    1       2      3
yellow     8    9      10     11
删除列还要指明从哪个轴删除元素。
>>> frame.drop(['pen', 'pencil'], axis = 1)
        ball  paper
red        0      3
blue       4      7
yellow     8     11
white     12     15

4. DataFrame和Series之间的运算

>>> frame
        ball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15
>>> s = pd.Series(np.arange(4), ['ball', 'pen', 'pencil', 'paper'])
按照frame的列名生成Series
>>> s
ball      0
pen       1
pencil    2
paper     3
dtype: int32
>>> frame - s
        ball  pen  pencil  paper
red        0    0       0      0
blue       4    4       4      4
yellow     8    8       8      8
white     12   12      12     12
一一对应相减
调整一些s中'paper'和'pencil'的位置
>>> s = pd.Series(np.arange(4), ['ball', 'pen', 'paper', 'pencil'])
>>> frame - s
        ball  paper  pen  pencil
red        0      1    0      -1
blue       4      5    4       3
yellow     8      9    8       7
white     12     13   12      11
发现还是可以一一对应
新增一列'mug'
>>> s['mug'] = 10
>>> s
ball       0
pen        1
paper      2
pencil     3
mug       10
dtype: int64
>>> frame - s
        ball  mug  paper  pen  pencil
red        0  NaN      1    0      -1
blue       4  NaN      5    4       3
yellow     8  NaN      9    8       7
white     12  NaN     13   12      11
发现会增加一列'mug‘但是元素值为NaN

5. 函数运用和映射

5.1. 按行或者列执行操作的函数

>>> frame
        ball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15

返回标量的apply()函数
>>> f = lambda x : x.max() - x.min() 
用apply()函数在DataFrame对象上调用函数
默认是对列使用
>>> frame.apply(f)
ball      12
pen       12
pencil    12
paper     12
dtype: int64
对行使用需要将axis选项设置为1
>>> frame.apply(f, axis = 1)
red       3
blue      3
yellow    3
white     3
dtype: int64

返回Series对象的apply()函数
>>> def f(x):
...   return pd.Series([x.min(), x.max()], index = ['min', 'max']) (index对应了DataFrame的index)
... 
>>> frame.apply(f)
     ball  pen  pencil  paper
min     0    1       2      3
max    12   13      14     15
>>> frame.apply(f, axis = 1)
        min  max
red       0    3
blue      4    7
yellow    8   11
white    12   15
我的理解:这里其实就是对每一列都跑一次f函数,对每一列都返回一个函数的值,如果指明axis = 1,就是对每一行都跑一次f函数,对每一行返回一个函数值。

5.2. 统计函数

>>> frame
        ball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15
>>> frame.sum()
ball      24
pen       28
pencil    32
paper     36
dtype: int64
>>> frame.mean()
ball      6.0
pen       7.0
pencil    8.0
paper     9.0
dtype: float64
>>> frame.describe()
            ball        pen     pencil      paper
count   4.000000   4.000000   4.000000   4.000000 (返回不为NaN的元素个数)
mean    6.000000   7.000000   8.000000   9.000000 (返回平均值)
std     5.163978   5.163978   5.163978   5.163978 (返回标准差)
min     0.000000   1.000000   2.000000   3.000000 
25%     3.000000   4.000000   5.000000   6.000000
50%     6.000000   7.000000   8.000000   9.000000
75%     9.000000  10.000000  11.000000  12.000000
max    12.000000  13.000000  14.000000  15.000000 (剩下的都能看懂)

6. 排序函数

6.1. 对Series排序

>>> s = pd.Series([5,0,3,8,4], index = ['red', 'blue', 'yellow', 'white', 'green'])
>>> s
red       5
blue      0
yellow    3
white     8
green     4
dtype: int64

按照索引名的字典序排序
>>> s.sort_index()
blue      0
green     4
red       5
white     8
yellow    3
dtype: int64
>>> s.sort_index(ascending=False) (降序)
yellow    3
white     8
red       5
green     4
blue      0
dtype: int64

按照值进行排序
>>> s.sort_values()
blue      0
yellow    3
green     4
red       5
white     8
dtype: int64
>>> s.sort_values(ascending=False)
white     8
red       5
green     4
yellow    3
blue      0
dtype: int64
书上写的是s.order(),但是自己实现起来出现错误,上网找了是sort_values()方法。

排位次操作(按照元素的值排位)
>>> s.rank()
red       4.0
blue      1.0
yellow    2.0
white     5.0
green     3.0
dtype: float64
>>> s.rank(ascending=False)
red       2.0
blue      5.0
yellow    4.0
white     1.0
green     3.0
dtype: float64

6.2. 对DataFrame排序

>>> frame
        ball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15

按照索引和列名排序
>>> frame.sort_index()
        ball  pen  pencil  paper
blue       4    5       6      7
red        0    1       2      3
white     12   13      14     15
yellow     8    9      10     11
>>> frame.sort_index(axis=1)
        ball  paper  pen  pencil
red        0      3    1       2
blue       4      7    5       6
yellow     8     11    9      10
white     12     15   13      14
注意这里都是对索引标签和对列名进行排序的,而不是按元素大小

按照值排序
按照列进行排序
>>> frame.sort_values(by='pen')
        ball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15
按照行进行排序
>>> frame.sort_values(by='blue', axis = 1)
        ball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15
这里书上应该是版本过旧,写的是sort_index()而不是sort_values()

7. 相关性和协方差

概念

相关性(correlation)

指两个变量之间的关系(或依赖关系)。

线性相关是指两个变量之间的直接关系。

相关性可以在-1(完全负相关)和+1(完美正相关)之间,0表示无线性关系。

协方差(covariance)

从直观上来看,协方差表示的是两个变量总体误差的期望。

如果两个变量的变化趋势一致,也就是说如果其中一个大于自身的期望值时另外一个也大于自身的期望值,那么两个变量之间的协方差就是正值;如果两个变量的变化趋势相反,即其中一个变量大于自身的期望值时另外一个却小于自身的期望值,那么两个变量之间的协方差就是负值。

二者关系

\[r_{ξ,η} = \frac{Cov(ξ,η)}{\sqrt{Dξ}\sqrt{Dη}} \]

其中r为相关性,Cov为协方差。

知乎上的解释

相关性和协方差的解释

>>> frame
        ball  pen  pencil  paper
red        0    1       2      3
blue       4    5       6      7
yellow     8    9      10     11
white     12   13      14     15

用cov()和corr()计算协方差和相关系数
这个是书上写的,并不是很懂意义
>>> frame.corr()
        ball  pen  pencil  paper
ball     1.0  1.0     1.0    1.0
pen      1.0  1.0     1.0    1.0
pencil   1.0  1.0     1.0    1.0
paper    1.0  1.0     1.0    1.0
>>> frame.cov()
             ball        pen     pencil      paper
ball    26.666667  26.666667  26.666667  26.666667
pen     26.666667  26.666667  26.666667  26.666667
pencil  26.666667  26.666667  26.666667  26.666667
paper   26.666667  26.666667  26.666667  26.666667

计算某列和某列的相关系数和协方差:
>>> frame.ball.corr(frame.pen)
1.0
>>> frame.pen.cov(frame.ball)
26.666666666666664

用corrwith()计算DataFrame的列(axis=0,默认)或行(axis=1)跟另外一个Series或DataFrame之间的相关系数
>>> frame.corrwith(frame.pen)
ball      1.0
pen       1.0
pencil    1.0
paper     1.0
dtype: float64
>>> frame.corrwith(frame.ix[0], axis = 1)
red       1.0
blue      1.0
yellow    1.0
white     1.0
dtype: float64

8. NaN数据

8.1. 为元素赋值NaN

使用np.NaN
>>> s = pd.Series([0,1,2,np.NaN,9], index = ['red', 'blue', 'yellow', 'white', 'green'])
>>> s
red       0.0
blue      1.0
yellow    2.0
white     NaN
green     9.0
dtype: float64
>>> s['white']
nan

8.2. 过滤NaN

删除Series中的NaN
使用dropna()函数或者使用notnull()筛选
>>> s.dropna()
red       0.0
blue      1.0
yellow    2.0
green     9.0
dtype: float64
>>> s[s.notnull()]
red       0.0
blue      1.0
yellow    2.0
green     9.0
dtype: float64

删除DataFrame中的NaN
>>> frame = pd.DataFrame([[6, np.NaN, 6], [np.NaN, np.NaN, np.NaN], [2, np.NaN, 5]], index = ['blue', 'green', 'red'], columns = ['ball', 'mug', 'pen'])
>>> frame
       ball  mug  pen
blue    6.0  NaN  6.0
green   NaN  NaN  NaN
red     2.0  NaN  5.0
使用dropna()只要行或列有一个NaN,该行或列就会被删除

>>> frame.dropna()
Empty DataFrame
Columns: [ball, mug, pen]
Index: []
可以发现因为每一行都有NaN,因此把每一行都删除了

用how指定值为'all',告知dropna()函数只删除所有元素均为NaN的行货列
>>> frame.dropna(how='all')
      ball  mug  pen
blue   6.0  NaN  6.0
red    2.0  NaN  5.0
>>> frame.dropna(how='all', axis = 1)
       ball  pen
blue    6.0  6.0
green   NaN  NaN
red     2.0  5.0

8.3. 为NaN元素填充其他值

>>> frame
       ball  mug  pen
blue    6.0  NaN  6.0
green   NaN  NaN  NaN
red     2.0  NaN  5.0

对所有NaN都填充0
>>> frame.fillna(0)
       ball  mug  pen
blue    6.0  0.0  6.0
green   0.0  0.0  0.0
red     2.0  0.0  5.0

指定列填充元素
>>> frame.fillna({'ball':1, 'mug':10, 'pen':0})
       ball   mug  pen
blue    6.0  10.0  6.0
green   1.0  10.0  0.0
red     2.0  10.0  5.0

貌似无法指定行填充元素,如果有错请务必告诉我
>>> frame.fillna({'blue':1, 'green':100, 'red':0}, axis = 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "E:\Python\Python3\lib\site-packages\pandas\core\frame.py", line 2754, in fillna
    downcast=downcast, **kwargs)
  File "E:\Python\Python3\lib\site-packages\pandas\core\generic.py", line 3639, in fillna
    raise NotImplementedError('Currently only can fill '
NotImplementedError: Currently only can fill with dict/Series column by column
>>> frame.fillna({'blue':1, 'green':100, 'red':0})
       ball  mug  pen
blue    6.0  NaN  6.0
green   NaN  NaN  NaN
red     2.0  NaN  5.0

9. 等级索引和分级

多级索引
>>> s = pd.Series(np.random.rand(8), index = [['white', 'white', 'white', 'blue', 'blue', 'red', 'blue', 'red'], ['up', 'down', 'right', 'up', 'down', 'up', 'left', 'left']])
>>> s
white  up       0.683135
       down     0.206419
       right    0.616636
blue   up       0.010939
       down     0.419153
red    up       0.632491
blue   left     0.060663
red    left     0.713318
dtype: float64

>>> s.index
MultiIndex(levels=[['blue', 'red', 'white'], ['down', 'left', 'right', 'up']],
           labels=[[2, 2, 2, 0, 0, 1, 0, 1], [3, 0, 2, 3, 0, 3, 1, 1]])

指明第一列索引
>>> s['blue']
up      0.010939
down    0.419153
left    0.060663
dtype: float64

指明第二列索引要类似切片用[:,第二列名],直接用[第二列名]会报错
>>> s[:,'up']
white    0.683135
blue     0.010939
red      0.632491
dtype: float64

>>> s['white','up']
0.68313456001550599

使用unstack()将使用等级索引的Series对象转换为一个DataFrame对象,把第二列索引转换为相应的列
>>> s.unstack()
           down      left     right        up
blue   0.419153  0.060663       NaN  0.010939
red         NaN  0.713318       NaN  0.632491
white  0.206419       NaN  0.616636  0.683135

逆操作,使用stack()将DataFrame对象转换为Series对象,列名为第二列索引
>>> frame
       ball  mug  pen
blue    6.0  NaN  6.0
green   NaN  NaN  NaN
red     2.0  NaN  5.0
>>> frame.stack()
blue  ball    6.0
      pen     6.0
red   ball    2.0
      pen     5.0
dtype: float64

对DataFrame,为行和列都定义等级索引。
>>> frame1 = pd.DataFrame(np.random.rand(16).reshape(4, 4), index = [['white', 'white', 'red', 'red'], ['up', 'down', 'up', 'down']], columns = [['pen', 'pen', 'paper', 'paper'], [1, 2, 1, 2]])
>>> frame1
                 pen               paper          
                   1         2         1         2
white up    0.461711  0.907535  0.720078  0.706302
      down  0.105371  0.673227  0.118255  0.401674
red   up    0.339669  0.307175  0.831875  0.699694
      down  0.946733  0.014064  0.716693  0.243006

9.1. 重新调整顺序和为层级排序

>>> frame1.columns.names = ['objects', 'id']
>>> frame1.index.names = ['colors', 'status']
>>> frame1
objects             pen               paper          
id                    1         2         1         2
colors status                                        
white  up      0.461711  0.907535  0.720078  0.706302
       down    0.105371  0.673227  0.118255  0.401674
red    up      0.339669  0.307175  0.831875  0.699694
       down    0.946733  0.014064  0.716693  0.243006

交换层级
>>> frame1.swaplevel('colors', 'status')
objects             pen               paper          
id                    1         2         1         2
status colors                                        
up     white   0.461711  0.907535  0.720078  0.706302
down   white   0.105371  0.673227  0.118255  0.401674
up     red     0.339669  0.307175  0.831875  0.699694
down   red     0.946733  0.014064  0.716693  0.243006

对某个层级的数据排序
书上用sortlevel()方法,应该还是旧版本原因
文档用的是sort_index()方法
>>> frame1.sort_index(level = 'colors')
objects             pen               paper          
id                    1         2         1         2
colors status                                        
red    down    0.946733  0.014064  0.716693  0.243006
       up      0.339669  0.307175  0.831875  0.699694
white  down    0.105371  0.673227  0.118255  0.401674
       up      0.461711  0.907535  0.720078  0.706302
>>> frame1.sort_index(level = 'objects', axis = 1)
objects           paper                 pen          
id                    1         2         1         2
colors status                                        
white  up      0.720078  0.706302  0.461711  0.907535
       down    0.118255  0.401674  0.105371  0.673227
red    up      0.831875  0.699694  0.339669  0.307175
       down    0

9.2. 按层级统计数据

对指定的层级进行统计
>>> frame1.sum(level='status')
objects       pen               paper          
id              1         2         1         2
status                                         
down     1.052105  0.687291  0.834948  0.644681
up       0.801380  1.214710  1.551954  1.405997
>>> frame1.sum(level='id', axis=1)
id                    1         2
colors status                    
white  up      1.181789  1.613837
       down    0.223626  1.074902
red    up      1.171545  1.006870
       down    1.663426  0.257070
posted @ 2017-06-23 00:19  Shadowdsp  阅读(1136)  评论(2编辑  收藏  举报