numpy
函数
argpartition
numpy.argpartition:是将第k大的数字,放在第k个位置。类似于快排找第k大的数,对其它数不做排序,比较省计算。
参考https://zhuanlan.zhihu.com/p/35325758
pandas
TODO
https://pandas.pydata.org/pandas-docs/stable/getting_started/10min.html#grouping
基本类型
panda 对象、索引都有 name 属性
series,可以认为它是一个长度固定且有序的字典
索引index,可以指定字符串数组为索引,根据此数组顺序进行排序,索引对象是不可变的,无法修改索引对象。
index[1]='d' # TypeError
值 value
dataframe,表示矩阵的数据表,行列索引都用,列索引一般由你指定,行索引可以自动生成,可以嵌套 dataframe
当你将列表或者数组赋值给列时,长度必须与 DataFrame 匹配
列是 series?同一列有相同的信息(数据类型)。行是 dataframe?
索引
Frame["colunm"]
可以获取列,frame.colunm
也可以,但是必须是有效的 Python 值,不存在键时会报错
Frame["colunm"]=arrange(6)
可以创建新的列,但是Frame.colunm=arrange(6)
不可以
索引像数组一样,但是方法像集合
reindex
df2=df.reindex(index=['a','b','c'],columns=['f','d','w'])
method=’ffile’,向前填充,’bfill’向后填充
fill_value=0 这是填充值
drop
删除 指定行、列,并返回新的对象,如果要修改原对象,可以设置 inplace=True
data.drop(["row1"])
data.drop(["col1"],axis=1)
data.drop(["col1"],axis=1,inplace=True)
数值切片时与 Python 一致不含之后一列,但是字符串切片时,是包含最后的。
loc 与 iloc
loc 轴标签,iloc 整数标签
data.loc[[1,2],[3,0,1]]
loc[:1] # 包含 1
iloc[:1] # 不包含1 ,有点坑
排序
sort_index(axis=)
,对索引进行排序
sort_values(by=['a','b'])
,对值进行排序
缺失值
na : not available
dropna 过滤掉 na (how='all', axis=1,thresh=2)全部是 na 时才是删除,并指定为列,thresh 表示只删除第2列或者行
fillna 替换 na
isnull 判断是否为 na
notnull
创建对象
series
s = pd.Series([1, 3, 5, np.nan, 6, 8])
dataFrame
传递数组
dates = pd.date_range('20130101', periods=6) # 创建时间列表,作为下面的索引
"""
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04','2013-01-05', '2013-01-06'], dtype='datetime64[ns]', freq='D')
"""
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD')) # index是行索引,columns 是列索引
"""
A B C D
2013-01-01 0.469112 -0.282863 -1.509059 -1.135632
2013-01-02 1.212112 -0.173215 0.119209 -1.044236
2013-01-03 -0.861849 -2.104569 -0.494929 1.071804
2013-01-04 0.721555 -0.706771 -1.039575 0.271860
2013-01-05 -0.424972 0.567020 0.276232 -1.087401
2013-01-06 -0.673690 0.113648 -1.478427 0.524988
"""
传递字典
df2 = pd.DataFrame({'A': 1.,
'B': pd.Timestamp('20130102'),
'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'})
"""
A B C D E F
0 1.0 2013-01-02 1.0 3 test foo
1 1.0 2013-01-02 1.0 3 train foo
2 1.0 2013-01-02 1.0 3 test foo
3 1.0 2013-01-02 1.0 3 train foo
"""
查看
查看部分内容
df.head()
df.tail(3)
查看索引
df.index # 行索引
df.columns # 列索引
转为 numpy
df.to_numpy()
Out[17]:
array([[ 0.4691, -0.2829, -1.5091, -1.1356],
[ 1.2121, -0.1732, 0.1192, -1.0442],
[-0.8618, -2.1046, -0.4949, 1.0718],
[ 0.7216, -0.7068, -1.0396, 0.2719],
[-0.425 , 0.567 , 0.2762, -1.0874],
[-0.6737, 0.1136, -1.4784, 0.525 ]])
使用
DataFrame.to_numpy()
](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html#pandas.DataFrame.to_numpy) 有时代价会非常大,特别是当每列数据类型不同的时候,这是pandas 与 NumPy本质的不同造成的: 整个NumPy数组只有一种数据类型 ,而 pandas 的每一列都可以是不同的数据类型. 当你使用DataFrame.to_numpy()
, pandas 要选择一种能覆盖 DataFrame 中所有数据的 NumPy dtype ,最终往往是object
, 这就需要将每个值都转为 Python object类型。
查看数值类型的列的统计信息
df.describe()
”“”
count 6.000000 6.000000 6.000000 6.000000
mean 0.073711 -0.431125 -0.687758 -0.233103
std 0.843157 0.922818 0.779887 0.973118
min -0.861849 -2.104569 -1.509059 -1.135632
25% -0.611510 -0.600794 -1.368714 -1.076610
50% 0.022070 -0.228039 -0.767252 -0.386188
75% 0.658444 0.041933 -0.034326 0.461706
max 1.212112 0.567020 0.276232 1.071804
“”“
转置
df.T
排序
索引排序
默认是对行索引排序,axis=1 时对列索引排序
df.sort_index(axis=1, ascending=False) # 列索引逆序
"""
D C B A
2013-01-01 -1.135632 -1.509059 -0.282863 0.469112
2013-01-02 -1.044236 0.119209 -0.173215 1.212112
2013-01-03 1.071804 -0.494929 -2.104569 -0.861849
2013-01-04 0.271860 -1.039575 -0.706771 0.721555
2013-01-05 -1.087401 0.276232 0.567020 -0.424972
2013-01-06 0.524988 -1.478427 0.113648 -0.673690
"""
内容排序
df.sort_values(by='B')
"""
A B C D
2013-01-03 -0.861849 -2.104569 -0.494929 1.071804
2013-01-04 0.721555 -0.706771 -1.039575 0.271860
2013-01-01 0.469112 -0.282863 -1.509059 -1.135632
2013-01-02 1.212112 -0.173215 0.119209 -1.044236
2013-01-06 -0.673690 0.113648 -1.478427 0.524988
2013-01-05 -0.424972 0.567020 0.276232 -1.087401
"""
选择
某行、某列
列选择:df['A']
等价于 df.A
行切片:df[0:3]
一大片
loc:通过 label
通过 label 选择,指定哪些行,哪些列
In [28]: df.loc['20130102':'20130104', ['A', 'B']]
Out[28]:
A B
2013-01-02 1.212112 -0.173215
2013-01-03 -0.861849 -2.104569
2013-01-04 0.721555 -0.706771
at
快速定位一个值 (等价于上面的方法):
In [31]: df.at[dates[0], 'A']
Out[31]: 0.4691122999071863
iloc:通过下标
指定行
In [32]: df.iloc[3]
Out[32]:
A 0.721555
B -0.706771
C -1.039575
D 0.271860
Name: 2013-01-04 00:00:00, dtype: float64
指定连续的行与列
In [33]: df.iloc[3:5, 0:2]
Out[33]:
A B
2013-01-04 0.721555 -0.706771
2013-01-05 -0.424972 0.567020
指定某些行与列
In [34]: df.iloc[[1, 2, 4], [0, 2]]
Out[34]:
A C
2013-01-02 1.212112 0.119209
2013-01-03 -0.861849 -0.494929
2013-01-05 -0.424972 0.276232
iat
:快速获得一个值
In [38]: df.iat[1, 1]
Out[38]: -0.17321464905330858
# 等价于
In [37]: df.iloc[1, 1]
Out[37]: -0.17321464905330858
boolean
基本形式:df[条件表达式]
所有满足条件的
df[df > 0]
"""
A B C D
2013-01-01 0.469112 NaN NaN NaN
2013-01-02 1.212112 NaN 0.119209 NaN
2013-01-03 NaN NaN NaN 1.071804
2013-01-04 0.721555 NaN NaN 0.271860
2013-01-05 NaN 0.567020 0.276232 NaN
2013-01-06 NaN 0.113648 NaN 0.524988
"""
某一列满足条件的
df[df.A > 0]
"""
A B C D
2013-01-01 0.469112 -0.282863 -1.509059 -1.135632
2013-01-02 1.212112 -0.173215 0.119209 -1.044236
2013-01-04 0.721555 -0.706771 -1.039575 0.271860
"""
isin()
辅助过滤
df2 = df.copy()
df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three']
"""
A B C D E
2013-01-01 0.469112 -0.282863 -1.509059 -1.135632 one
2013-01-02 1.212112 -0.173215 0.119209 -1.044236 one
2013-01-03 -0.861849 -2.104569 -0.494929 1.071804 two
2013-01-04 0.721555 -0.706771 -1.039575 0.271860 three
2013-01-05 -0.424972 0.567020 0.276232 -1.087401 four
2013-01-06 -0.673690 0.113648 -1.478427 0.524988 three
"""
df2[df2['E'].isin(['two', 'four'])]
"""
A B C D E
2013-01-03 -0.861849 -2.104569 -0.494929 1.071804 two
2013-01-05 -0.424972 0.567020 0.276232 -1.087401 four
"""
赋值
新增一列
# 通过 series 新增
s1 = pd.Series([1, 2, 3, 4, 5, 6], index=pd.date_range('20130102', periods=6))
# 通过 numpy 新增
df.loc[:, 'D'] = np.array([5] * len(df))
通过 label 定位来赋值
In [48]: df.at[dates[0], 'A'] = 0
通过下标 position 定位来赋值
In [49]: df.iat[0, 1] = 0
经过上面 3 次操作后:
In [51]: df
Out[51]:
A B C D F
2013-01-01 0.000000 0.000000 -1.509059 5 NaN
2013-01-02 1.212112 -0.173215 0.119209 5 1.0
2013-01-03 -0.861849 -2.104569 -0.494929 5 2.0
2013-01-04 0.721555 -0.706771 -1.039575 5 3.0
2013-01-05 -0.424972 0.567020 0.276232 5 4.0
2013-01-06 -0.673690 0.113648 -1.478427 5 5.0
通过条件筛选赋值
In [52]: df2 = df.copy()
In [53]: df2[df2 > 0] = -df2
In [54]: df2
Out[54]:
A B C D F
2013-01-01 0.000000 0.000000 -1.509059 -5 NaN
2013-01-02 -1.212112 -0.173215 -0.119209 -5 -1.0
2013-01-03 -0.861849 -2.104569 -0.494929 -5 -2.0
2013-01-04 -0.721555 -0.706771 -1.039575 -5 -3.0
2013-01-05 -0.424972 -0.567020 -0.276232 -5 -4.0
2013-01-06 -0.673690 -0.113648 -1.478427 -5 -5.0
缺失值处理
默认 nan 不参与计算
判断 nan
In [60]: pd.isna(df1)
Out[60]:
A B C D F E
2013-01-01 False False False False True False
2013-01-02 False False False False False False
2013-01-03 False False False False False True
2013-01-04 False False False False False True
删除含有 NaN 的行
In [58]: df1.dropna(how='any')
Out[58]:
A B C D F E
2013-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0
填充NaN
In [59]: df1.fillna(value=5)
Out[59]:
A B C D F E
2013-01-01 0.000000 0.000000 -1.509059 5 5.0 1.0
2013-01-02 1.212112 -0.173215 0.119209 5 1.0 1.0
2013-01-03 -0.861849 -2.104569 -0.494929 5 2.0 5.0
2013-01-04 0.721555 -0.706771 -1.039575 5 3.0 5.0
操作
统计
# 平均值
df.mean()
# 频率计算(series 方法)
s = pd.Series(np.random.randint(0, 7, size=10))
s.value_counts()
map
map()
是Series对象的一个函数,DataFrame中没有map(),map()的功能是将一个自定义函数作用于Series对象的每个元素。
aplay
apply()
函数的功能是将一个自定义函数作用于DataFrame的行或者列
df.apply(np.cumsum)
"""
A B C D F
2013-01-01 0.000000 0.000000 -1.509059 5 NaN
2013-01-02 1.212112 -0.173215 -1.389850 10 1.0
2013-01-03 0.350263 -2.277784 -1.884779 15 3.0
2013-01-04 1.071818 -2.984555 -2.924354 20 6.0
2013-01-05 0.646846 -2.417535 -2.648122 25 10.0
2013-01-06 -0.026844 -2.303886 -4.126549 30 15.0
"""
df.apply(lambda x: x.max() - x.min())
"""
A 2.073961
B 2.671590
C 1.785291
D 0.000000
F 4.000000
dtype: float64
"""
applymap
applymap()
函数的功能是将自定义函数作用于DataFrame的所有元素
字符串方法
Note that pattern-matching in str generally uses regular expressions by default. str 是通过正则匹配到的
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
s.str.lower()
合并数据
append
添加一行
df = pd.DataFrame(np.random.randn(8, 4), columns=['A', 'B', 'C', 'D'])
s = df.iloc[3] # 选择原表中的第 4 行
df.append(s, ignore_index=True) # 添加一行到表的最后
concat
多行拼接
df = pd.DataFrame(np.random.randn(10, 4))
In [74]: df
Out[74]:
0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
# break it into pieces
In [75]: pieces = [df[:3], df[3:7], df[7:]] # 从第4 、8行拆开,分成 3 份,然后再进行拼接,还原会原表
In [76]: pd.concat(pieces)
Out[76]:
0 1 2 3
0 -0.548702 1.467327 -1.015962 -0.483075
1 1.637550 -1.217659 -0.291519 -1.745505
2 -0.263952 0.991460 -0.919069 0.266046
3 -0.709661 1.669052 1.037882 -1.705775
4 -0.919854 -0.042379 1.247642 -0.009920
5 0.290213 0.495767 0.362949 1.548106
6 -1.131345 -0.089329 0.337863 -0.945867
7 -0.932132 1.956030 0.017587 -0.016692
8 -0.575247 0.254161 -1.143704 0.215897
9 1.193555 -0.077118 -0.408530 -0.862495
join
Sql 风格的合并
In [82]: left = pd.DataFrame({'key': ['foo', 'bar'], 'lval': [1, 2]})
In [83]: right = pd.DataFrame({'key': ['foo', 'bar'], 'rval': [4, 5]})
In [84]: left
Out[84]:
key lval
0 foo 1
1 bar 2
In [85]: right
Out[85]:
key rval
0 foo 4
1 bar 5
In [86]: pd.merge(left, right, on='key')
Out[86]:
key lval rval
0 foo 1 4
1 bar 2 5
分组
类似于数据库的 group by
,会有以下步骤
- 根据条件来分组
- 对每个组应用指定的方法function
- 将结果汇总到数据类型中(serie或者 dataframe)
In [91]: df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar',
....: 'foo', 'bar', 'foo', 'foo'],
....: 'B': ['one', 'one', 'two', 'three',
....: 'two', 'two', 'one', 'three'],
....: 'C': np.random.randn(8),
....: 'D': np.random.randn(8)})
....:
In [92]: df
Out[92]:
A B C D
0 foo one -1.202872 -0.055224
1 bar one -1.814470 2.395985
2 foo two 1.018601 1.552825
3 bar three -0.595447 0.166599
4 foo two 1.395433 0.047609
5 bar two -0.392670 -0.136473
6 foo one 0.007207 -0.561757
7 foo three 1.928123 -1.623033
根据一列分组
In [93]: df.groupby('A').sum()
Out[93]:
C D
A
bar -2.802588 2.42611
foo 3.146492 -0.63958
根据 多列分组
In [94]: df.groupby(['A', 'B']).sum()
Out[94]:
C D
A B
bar one -1.814470 2.395985
three -0.595447 0.166599
two -0.392670 -0.136473
foo one -1.195665 -0.616981
three 1.928123 -1.623033
two 2.414034 1.600434
时间处理
时间 序列生成
rng = pd.date_range('3/6/2012 00:00', periods=5, freq='D')
#起始时间点,数据量,跨度(D:day,M:minute,S:second)
Reshaping TODO
TODO