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
网友评论