我爱编程

Pandas 的基本用法

2018-03-11  本文已影响0人  Manchangdx

Series 用来创建一维数组:

In [121]: import pandas as pd

In [122]: from pandas import Series, DataFrame

In [123]: s = Series(range(5))

In [124]: s
Out[124]: 
0    0
1    1
2    2
3    3
4    4
dtype: int64

In [125]: type(s)
Out[125]: pandas.core.series.Series

定制索引:

In [126]: s = Series(range(1,6), index=list('abcde'))

In [127]: s
Out[127]: 
a    1
b    2
c    3
d    4
e    5
dtype: int64

In [128]: s.index
Out[128]: Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

In [129]: s.index.name = '索引'

In [130]: s.index
Out[130]: Index(['a', 'b', 'c', 'd', 'e'], dtype='object', name='索引')

DataFrame 创建二维数组:

In [144]: df = DataFrame(np.random.randn(3,4),
     ...: index=list('abc'),
     ...: columns=list('ABCD')
     ...: )

In [145]: df
Out[145]: 
          A         B         C         D
a  0.042214  0.582815 -1.100619  1.144724
b  0.901591  0.502494  0.900856 -0.683728
c -0.122890 -0.935769 -0.267888  0.530355

In [146]: df.index
Out[146]: Index(['a', 'b', 'c'], dtype='object')

In [147]: df.columns
Out[147]: Index(['A', 'B', 'C', 'D'], dtype='object')

In [148]: type(df)
Out[148]: pandas.core.frame.DataFrame

重要提醒:Series 和 DataFrame 的定制索引切片都是左闭右闭的
     默认整数索引切片与 Python 列表一样是左闭右开的

Series 选择一个元素,结果数据类型是 numpy 数值;选择多个,结果是 Series 类型

示例略过~

DataFrame 的选择:

In [198]: df
Out[198]: 
          A         B         C         D         E
a  1.198918  0.185156 -0.375285 -0.638730  0.423494
b  0.077340 -0.343854  0.043597 -0.620001  0.698032
c -0.447129  1.224508  0.403492  0.593579 -1.094912
d  0.169382  0.740556 -0.953701 -0.266219  0.032615

# 同时选择行和列只能用 loc 和 iloc 方法,原理就是切片
# loc 使用定制索引;iloc 使用默认索引,即整数索引
# 选择多行多列的结果的数据类型:DataFrame
# 选择单行多列、多行单列的结果的数据类型是 Series
# 选择单行单列,也就是一个元素的结果的数据类型是 numpy 数值
In [199]: df.loc['b': 'c', 'B': 'D']
Out[199]: 
          B         C         D
b -0.343854  0.043597 -0.620001
c  1.224508  0.403492  0.593579

In [200]: df.loc[list('bc'), list('BCD')]
Out[200]: 
          B         C         D
b -0.343854  0.043597 -0.620001
c  1.224508  0.403492  0.593579

In [201]: df.iloc[2:, ::2]
Out[201]: 
          A         C         E
c -0.447129  0.403492 -1.094912
d  0.169382 -0.953701  0.032615

In [202]: df.iloc[[2,3], [0,2,4]]
Out[202]: 
          A         C         E
c -0.447129  0.403492 -1.094912
d  0.169382 -0.953701  0.032615
# 只选行有 4 种方法,老厉害了

# 1、切片
# 默认索引和定制索引均可, df[m: n]  df['a': 'b']
# 注意切片必须有冒号,即使只选一行,否则报错
# 这种方法选择一行或多行,结果都是 DataFrame 类型
In [204]: df[:2]
Out[204]: 
          A         B         C         D         E
a  1.198918  0.185156 -0.375285 -0.638730  0.423494
b  0.077340 -0.343854  0.043597 -0.620001  0.698032

In [205]: df[1: 2]
Out[205]: 
          A         B         C         D         E
b  0.077340 -0.343854  0.043597 -0.620001  0.698032

In [206]: type(df[1: 2])
Out[206]: pandas.core.frame.DataFrame

In [207]: df['b':'b']
Out[207]: 
          A         B         C         D         E
b  0.077340 -0.343854  0.043597 -0.620001  0.698032

# 2、筛选法
# 一种特殊且实用的选行方法,结果的数据类型为 DataFrame
In [39]: df
Out[39]: 
   A  B   C   D
a  0  1   2   3
b  4  5   6   7
c  8  9  10  11

In [40]: df[df.C==6]
Out[40]: 
   A  B  C  D
b  4  5  6  7

In [41]: df[df.B > 3]
Out[41]:
   A  B   C   D
b  4  5   6   7
c  8  9  10  11

In [43]: df[df.index=='a']  # 只能选一行
Out[43]:
   A  B  C  D
a  0  1  2  3

In [44]: df[df.index.isin(['a', 'c'])]  # isin 方法可以选择多行
Out[44]:
   A  B   C   D
a  0  1   2   3
c  8  9  10  11

# 3、定制索引 
# df.loc['a'] df.loc['a': 'b'] 有冒号数据类型是 DataFrame,否则数据类型是 Series
# df.loc[df.index[m]]  df.loc[df.index[m: n]] 结果数据类型同上
# df.loc[df.列名=='a'] 此方法只能选一行且不会报错,结果的数据类型是 DataFrame
In [208]: df.loc['a']
Out[208]: 
A   1.198918
B   0.185156
C   -0.375285
D   -0.638730
E   0.423494
Name: a, dtype: float64

In [209]: df.loc['a':'b']
Out[209]: 
          A         B         C         D         E
a  1.198918  0.185156 -0.375285 -0.638730  0.423494
b  0.077340 -0.343854  0.043597 -0.620001  0.698032

In [210]: df.loc[df.index[1: 2]]
Out[210]: 
          A         B         C         D       E
b  0.077340 -0.343854  0.043597 -0.620001  0.698032

# 4、默认索引 
# df.iloc[m]  df.iloc[m: n] 同上
# 有冒号数据类型是 DataFrame,否则数据类型是 Series
# df.iloc[df.index=='a'] 此方法也只能选一行,它等同于 df.loc[df.index=='a']
In [211]: df.iloc[df.index=='a']
Out[211]: 
          A         B         C         D         E
a 1.198918  0.185156 -0.375285 -0.638730  0.423494
# 只选列比较简单了
In [222]: df.A      # 用属性只能选一列
Out[222]: 
a    1.198918
b    0.077340
c   -0.447129
d    0.169382
Name: A, dtype: float64

In [223]: df['A']   # 这种方法也可以选多列:df[['A', 'B', 'C']]
Out[223]: 
a    1.198918
b    0.077340
c   -0.447129
d    0.169382
Name: A, dtype: float64

In [224]: df[df.columns[::2]]   # 用索引可以选多列
Out[224]: 
          A         C         E
a  1.198918 -0.375285  0.423494
b  0.077340  0.043597  0.698032
c -0.447129  0.403492 -1.094912
d  0.169382 -0.953701  0.032615

head 和 tail 方法获取前几行和后几行,不写参数的话默认是 5 个:

In [203]: s = Series(np.arange(1,6))

In [204]: s
Out[204]: 
0    1
1    2
2    3
3    4
4    5
dtype: int64

In [205]: s.head(2)
Out[205]: 
0    1
1    2
dtype: int64

In [206]: s.tail(2)
Out[206]: 
3    4
4    5
dtype: int64

In [207]: df = DataFrame(np.random.rand(5,6))

In [208]: df.head(2)
Out[208]: 
          0         1         2         3         4         5
0  0.792248  0.581068  0.937699  0.659247  0.532455  0.817163
1  0.218331  0.672623  0.798196  0.112225  0.312836  0.312792

In [209]: df.tail(2)
Out[209]: 
          0         1         2        3         4         5
3  0.998442  0.512222  0.001889  0.24681  0.833295  0.121865
4  0.855242  0.951448  0.050019  0.24448  0.116706  0.745283

DataFrame 多维数组增加行和列:

In [184]: df = DataFrame(np.random.normal(1,2,12).reshape(3,4),
     ...: index=list('abc'),
     ...: columns=list('ABCD')
     ...: )

In [185]: df
Out[185]: 
          A         B         C         D
a  2.369567  0.380613 -0.053129  3.094361
b -0.945000  2.137485  0.243314  3.112989
c  2.345169  2.954993 -1.227557  2.485193

In [186]: df.loc['d'] = np.random.normal(1,2)   # 增加一行,索引为 'd'

In [187]: df
Out[187]: 
          A         B         C         D
a  2.369567  0.380613 -0.053129  3.094361
b -0.945000  2.137485  0.243314  3.112989
c  2.345169  2.954993 -1.227557  2.485193
d  1.276319  1.276319  1.276319  1.276319

In [188]: df['E'] = np.random.normal(1,2)       # 增加一列,字段为 'E'

In [189]: df
Out[189]: 
          A         B         C         D         E
a  2.369567  0.380613 -0.053129  3.094361  1.526591
b -0.945000  2.137485  0.243314  3.112989  1.526591
c  2.345169  2.954993 -1.227557  2.485193  1.526591
d  1.276319  1.276319  1.276319  1.276319  1.526591

# 若无定制索引,df.iloc[m] 增加一行,df[m] 增加一列

DataFrame 多维数组删除行和列:

# 删除行
In [252]: df
Out[252]: 
          A         B         C         D         E
a  2.972670  1.427068  5.381399 -2.792722 -1.545118
b -0.293833  2.802974  6.056651  0.502730 -1.545118
c  1.087338  0.547372  3.662914  0.425384 -1.545118
d  2.360140  2.360140  2.360140  2.360140 -1.545118

# 没有定制 index 的话,可以这样:df.drop(m) df.drop([m, n])
# 定制了 index 就只能用下面的方法删除行
In [253]: df.drop('a')         # 删除一行
Out[253]: 
          A         B         C         D         E
b -0.293833  2.802974  6.056651  0.502730 -1.545118
c  1.087338  0.547372  3.662914  0.425384 -1.545118
d  2.360140  2.360140  2.360140  2.360140 -1.545118

In [254]: df.drop(list('bc'))  # 删除多行
Out[254]: 
         A         B         C         D         E
a  2.97267  1.427068  5.381399 -2.792722 -1.545118
d  2.36014  2.360140  2.360140  2.360140 -1.545118

In [255]: df                   # 并不会替换原来的 df
Out[255]: 
          A         B         C         D         E
a  2.972670  1.427068  5.381399 -2.792722 -1.545118
b -0.293833  2.802974  6.056651  0.502730 -1.545118
c  1.087338  0.547372  3.662914  0.425384 -1.545118
d  2.360140  2.360140  2.360140  2.360140 -1.545118

In [257]: df.drop(list('ab'), inplace=True)  # 想要替换,加个 inplace 参数

In [258]: df
Out[258]: 
          A         B         C         D         E
c  1.087338  0.547372  3.662914  0.425384 -1.545118
d  2.360140  2.360140  2.360140  2.360140 -1.545118
# 下面说一下删除列
# df.pop('A') 和 del df['A'] 只能删一列
In [303]: df
Out[303]: 
          A         B         C         D         E         F
a -0.606998  0.106223 -1.525680  0.795026 -0.374438  0.134048
b  1.202055  0.284748  0.262467  0.276499 -0.733272  0.836005
c  1.543359  0.758806  0.884909 -0.877282 -0.867787 -1.440876

In [304]: df.pop('F')
Out[304]: 
a    0.134048
b    0.836005
c   -1.440876
Name: F, dtype: float64

In [305]: df
Out[305]: 
          A         B         C         D         E
a -0.606998  0.106223 -1.525680  0.795026 -0.374438
b  1.202055  0.284748  0.262467  0.276499 -0.733272
c  1.543359  0.758806  0.884909 -0.877282 -0.867787

In [306]: del df['C']

In [307]: df
Out[307]: 
          A         B         D         E
a -0.606998  0.106223  0.795026 -0.374438
b  1.202055  0.284748  0.276499 -0.733272
c  1.543359  0.758806 -0.877282 -0.867787

# 上面删除行用到的 drop 方法有个默认参数 axis=0,即默认删除行
# 如果设置 axis=1 就会删除列,注意 inplace 参数的用法亦同上
In [308]: df.drop('D', axis=1)
Out[308]: 
          A         B         E
a -0.606998  0.106223 -0.374438
b  1.202055  0.284748 -0.733272
c  1.543359  0.758806 -0.867787

In [310]: df.drop(['D', 'E'], axis=1, inplace=True)

In [311]: df
Out[311]: 
          A         B
a -0.606998  0.106223
b  1.202055  0.284748
c  1.543359  0.758806

DataFrame 数据合并的两种方法:concat / merge

In [22]: df1 = DataFrame(np.random.randn(2,3))

In [23]: df2 = DataFrame(np.random.randn(2,2))

In [24]: df1
Out[24]: 
          0         1         2
0  0.530403  0.093942  0.216301
1 -0.242924  0.191085 -0.839217

In [25]: df2
Out[25]: 
          0        1
0  0.802830 -0.85139
1 -0.568546  0.03800

In [26]: pd.concat([df1, df2])           # 默认将两个数组纵向拼接
Out[26]: 
          0         1         2
0  0.530403  0.093942  0.216301
1 -0.242924  0.191085 -0.839217
0  0.802830 -0.851390       NaN
1 -0.568546  0.038000       NaN

In [27]: pd.concat([df1, df2], axis=1)   # 将两个数组横向拼接
Out[27]: 
          0         1         2         0        1
0  0.530403  0.093942  0.216301  0.802830 -0.85139
1 -0.242924  0.191085 -0.839217 -0.568546  0.03800

# 三个也能拼接
In [34]: df3 = DataFrame(np.random.randn(), index=['a'], columns=['A'])

In [35]: pd.concat([df1, df2, df3])
Out[35]: 
          0         1         2         A
0  0.530403  0.093942  0.216301       NaN
1 -0.242924  0.191085 -0.839217       NaN
0  0.802830 -0.851390       NaN       NaN
1 -0.568546  0.038000       NaN       NaN
a       NaN       NaN       NaN  0.489118

# 如果发出如下警告
# FutureWarning: Sorting because non-concatenation axis is not aligned
# 可以增加一个参数:pd.concat([df, df1], sort=True)
# merge 方法会根据两个数组的相同列,来横向合并
# 注意这个相同列不仅列名相同,数据也得一致,如果有不一致的行,则自动舍弃
In [36]: df1 = DataFrame({
    ...: 'name': ['Linux 基础', 'flask 基础'],
    ...: 'id': [123, 234],
    ...: 'student': [2, 333]
    ...: })

In [37]: df2 = DataFrame({'id': [123, 234], 'learn_time': [111, 222]})

In [39]: df1
Out[39]: 
    id      name  student
0  123  Linux 基础        2
1  234  flask 基础      333

In [40]: df2
Out[40]: 
    id  learn_time
0  123         111
1  234         222

In [41]: pd.merge(df1, df2)   # id 这列,两个数组完全一样,会自动根据这列横向合并
Out[42]: 
    id      name  student  learn_time
0  123  Linux 基础        2         111
1  234  flask 基础      333         222

DataFrame 数据分组

In [41]: df = DataFrame({'id': [12, 23, 12], 'min': [123, 4, 543]})

In [42]: df
Out[42]: 
   id  min
0  12  123
1  23    4
2  12  543

# 根据 id 字段分组并求和
# groupby 分组就是将数值相同的行放一起
In [43]: df.groupby('id').sum()
Out[43]: 
    min
id     
12  666
23    4

Pandas 缺失值自动填充
上文数据合并中出现了一些 NaN 数据,就是 Not a Numpy(不是 numpy 数值)

In [62]: s1 = Series(range(1, 4), index=list('abc'))

In [63]: s2 = Series(range(4, 7), index=list('bcd'))

In [64]: s1
Out[64]: 
a    1
b    2
c    3
dtype: int64

In [65]: s2
Out[65]: 
b    4
c    5
d    6
dtype: int64

In [66]: s1 + s2
Out[66]: 
a    NaN
b    6.0
c    8.0
d    NaN
dtype: float64

In [67]: s1.add(s2, fill_value=0)  # 此参数进行缺失值自动填充
Out[67]: 
a    1.0
b    6.0
c    8.0
d    6.0
dtype: float64

In [68]: s1.add(s2, fill_value=100)
Out[68]: 
a    101.0
b      6.0
c      8.0
d    106.0
dtype: float64

# DataFrame 也一样,不再举例

DataFrame 运算

In [77]: df
Out[77]: 
   A   B   C   D
a  1   2   3   4
b  5   6   7   8
c  9  10  11  12

# 创建函数,x 指的是行或列,运算结果为极差
In [78]: f = lambda x: x.max() - x.min()

In [79]: df.apply(f)           # 默认 axis=0 对列进行计算
Out[79]: 
A    8
B    8
C    8
D    8
dtype: int64

In [80]: df.apply(f, axis=1)   # 对行进行计算
Out[80]: 
a    3
b    3
c    3
dtype: int64

In [81]: df                    # 并不会改变原数据
Out[81]: 
   A   B   C   D
a  1   2   3   4
b  5   6   7   8
c  9  10  11  12

# 或者直接将函数写入参数位置
In [89]: df.apply(lambda x: x**2)
Out[89]: 
    A    B    C    D
a   1    4    9   16
b  25   36   49   64
c  81  100  121  144

# 更简单的写法:
In [94]: df**2
Out[94]: 
    A    B    C    D
a   1    4    9   16
b  25   36   49   64
c  81  100  121  144

pandas 常用统计,以 DataFrame 为例,Series 也类似:

In [9]: df
Out[9]: 
   A   B   C   D
a  1   2   3   4
b  5   6   7   8
c  9  10  11  12

In [10]: df.sum()      # 默认 axis=0 按列求和
Out[10]: 
A    15
B    18
C    21
D    24
dtype: int64

In [11]: df.sum(axis=1)
Out[11]: 
a    10
b    26
c    42
dtype: int64

In [12]: df.mean()
Out[12]: 
A    5.0
B    6.0
C    7.0
D    8.0
dtype: float64

In [13]: df.mean(axis=1)
Out[13]: 
a     2.5
b     6.5
c    10.5
dtype: float64
In [14]: df
Out[14]: 
   A   B   C   D
a  1   2   3   4
b  5   6   7   8
c  9  10  11  12

In [15]: df.describe()   # 按列计算常用信息
Out[15]: 
         A     B     C     D
count  3.0   3.0   3.0   3.0   # 元素数量
mean   5.0   6.0   7.0   8.0   # 平均值
std    4.0   4.0   4.0   4.0   # 标准差
min    1.0   2.0   3.0   4.0   # 最小值
25%    3.0   4.0   5.0   6.0   # 下四分位数
50%    5.0   6.0   7.0   8.0   # 中位数
75%    7.0   8.0   9.0  10.0   # 上四分位数
max    9.0  10.0  11.0  12.0   # 最大值

# 算法:n 为元素数量
# 25% 下四分位数:(n+3)/4 ; 75% 上四分位数:(3n+1)/4

火遁 · pandas 排序之术

# Series 排序
In [10]: s = Series(np.random.randn(4), index=list('asdf'))

In [11]: s
Out[11]: 
a    1.742297
s   -0.151595
d    1.479944
f   -0.161126
dtype: float64

In [12]: s.sort_index()    # 按索引排序,默认升序
Out[12]: 
a    1.742297
d    1.479944
f   -0.161126
s   -0.151595
dtype: float64

In [13]: s.sort_values()   # 按值排序,默认升序
Out[13]: 
f   -0.161126
s   -0.151595
d    1.479944
a    1.742297
dtype: float64

In [14]: s.sort_values(ascending=False)  # 按值降序排列
Out[14]: 
a    1.742297
d    1.479944
s   -0.151595
f   -0.161126
dtype: float64

# 还有个参数 inplace 默认等于 False,不举例了
# DataFrame 排序
In [42]: df = DataFrame([(1, 2, 1), (111, 22, 11), (111, 2, 9)],
    ...:     index=list('asd'), columns=list('ASD'))
    ...:     

In [43]: df
Out[43]: 
     A   S   D
a    1   2   1
s  111  22  11
d  111   2   9

In [44]: df.sort_index()          # 按索引排序
Out[44]: 
     A   S   D
a    1   2   1
d  111   2   9
s  111  22  11

In [45]: df.sort_index(axis=1)   # 按 columns 排序
Out[45]: 
     A   D   S
a    1   1   2
s  111  11  22
d  111   9   2

In [46]: df.sort_values(by='D')  # 按某一字段的值排序,默认升序
Out[46]: 
     A   S   D
a    1   2   1
d  111   2   9
s  111  22  11

In [47]: df
Out[47]: 
     A   S   D
a    1   2   1
s  111  22  11
d  111   2   9

In [48]: df.sort_values(by=['A', 'D'])  # 先按 A 列排,如有相同值,按 D 列排
Out[48]: 
     A   S   D
a    1   2   1
d  111   2   9
s  111  22  11

In [49]: df.sort_values(by=['A', 'D'], ascending=[True, False])
Out[49]: 
     A   S   D
a    1   2   1
s  111  22  11
d  111   2   9
上一篇下一篇

猜你喜欢

热点阅读