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 属性

  1. series,可以认为它是一个长度固定且有序的字典

    1. 索引index,可以指定字符串数组为索引,根据此数组顺序进行排序,索引对象是不可变的,无法修改索引对象。

      index[1]='d'  # TypeError
      
    2. 值 value

  2. dataframe,表示矩阵的数据表,行列索引都用,列索引一般由你指定,行索引可以自动生成,可以嵌套 dataframe

  3. 当你将列表或者数组赋值给列时,长度必须与 DataFrame 匹配

  4. 列是 series?同一列有相同的信息(数据类型)。行是 dataframe?

索引

Frame["colunm"]可以获取列,frame.colunm 也可以,但是必须是有效的 Python 值,不存在键时会报错

Frame["colunm"]=arrange(6)可以创建新的列,但是Frame.colunm=arrange(6)不可以

索引像数组一样,但是方法像集合

image-20191215160830738

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

评论