zoukankan      html  css  js  c++  java
  • pandas 学习

    Pandas处理以下三个数据结构 ,这些数据结构构建在Numpy数组之上,这意味着它们很快。

    • 系列(Series)
    • 数据帧(DataFrame)
    • 面板(Panel)

    较高维数据结构是其较低维数据结构的容器。 DataFrameSeries的容器,PanelDataFrame的容器。

    数据结构 维数 描述
    系列(Series) 1 一维数组。均匀数据,大小不变,值可变
    数据帧(DataFrame) 2 二维数组。异构数据,大小可变,值可变
    面板(Panel) 3 三维数组。异构数据,大小可变,值可变

    导入模块

    import pandas as pd
    import numpy as np
    

    Series 操作

    系列(Series)是能够保存任何类型的数据(整数,字符串,浮点数,Python对象等)的一维标记数组。轴标签统称为索引。

    创建Pandas系列

    pandas.Series( data, index, dtype, copy)
    

    构造函数的参数如下

    参数 描述
    data 数据,如:ndarraylistconstants
    index 索引值必须是唯一的和散列的,与数据的长度相同。 默认np.arange(n)
    dtype dtype用于数据类型。如果没有,将推断数据类型
    copy 复制数据,默认为false

    使用各种输入创建一个系列:

    • 数组
    • 字典
    • 标量值或常数

    创建一个空的系列

    s = pd.Series()
    
    Series([], dtype: float64)
    

    从ndarray创建一个系列

    传递的索引必须具有相同的长度。不传递索引,默认的索引将是 ndarray 长度。

    data = np.array(['a','b','c','d'])
    s = pd.Series(data)
    s = pd.Series(data,index=[100,101,102,103])
    
    0   a
    1   b
    2   c
    3   d
    
    100  a
    101  b
    102  c
    103  d
    

    从字典创建一个系列

    不指定索引,则按排序顺序:字典key == 索引。

    指定索引,索引中与字典key相同的索引,字典value为值;没有的字典key索引值,索引顺序保持不变,缺少的元素使用NaN(不是数字)填充

    data = {'a' : 0., 'b' : 1., 'c' : 2.}
    s = pd.Series(data)
    s = pd.Series(data,index=['b','c','d','a'])
    
    a 0.0
    b 1.0
    c 2.0
    
    b 1.0
    c 2.0
    d NaN
    a 0.0
    

    从标量创建一个系列

    必须提供索引。将重复该值以匹配索引的长度。

    s = pd.Series(5, index=[0, 1, 2, 3])
    
    0  5
    1  5
    2  5
    3  5
    

    查看 Series 数据

    s[0]  # 根据索引
    s[:3]  # 根据索引切片
    s[-3:]
    s['a']  # 根据字典key的索引名称
    s[['a','c','d']]  # 根据多个索引名称的列表
    s[[1,2,3]]  # 根据多个索引的列表
    
    c  3
    d  4
    e  5
    

    查看不包含标签,则会出现异常

    print s['f']
    
    KeyError: 'f'
    

    DataFrame 操作

    创建数据帧DataFrame

    通过传递numpy数组,使用datetime索引和标记列来创建DataFrame

    dates = pd.date_range('20170101', periods=7)
    df = pd.DataFrame(np.random.randn(7,4), index=dates, columns=list('ABCD'))
    
    DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
                   '2017-01-05', '2017-01-06', '2017-01-07'],
                  dtype='datetime64[ns]', freq='D')
    --------------------------------
                       A         B         C         D
    2017-01-01 -0.732038  0.329773 -0.156383  0.270800
    2017-01-02  0.750144  0.722037 -0.849848 -1.105319
    2017-01-03 -0.786664 -0.204211  1.246395  0.292975
    2017-01-04 -1.108991  2.228375  0.079700 -1.738507
    2017-01-05  0.348526 -0.960212  0.190978 -2.223966
    2017-01-06 -0.579689 -1.355910  0.095982  1.233833
    2017-01-07  1.086872  0.664982  0.377787  1.012772
    

    通过传递字典来创建DataFrame。参考以下示例代码 -

    df2 = pd.DataFrame({ 'A' : 1.,
                         'B' : pd.Timestamp('20170102'),
                         '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 2017-01-02  1.0  3   test  foo
    1  1.0 2017-01-02  1.0  3  train  foo
    2  1.0 2017-01-02  1.0  3   test  foo
    3  1.0 2017-01-02  1.0  3  train  foo
    

    pandas报错:ValueError: If using all scalar values, you must pass an index

    字典转为DataFrame,字典中的value至少有一个有索引,长度才可以,所有值都没有索引,无法确定长度而报错。

    查看数据

    查看开头,结尾数据

    df.head()   # 前几行数据,不输入有默认行数为5
    df.tail(3)  # 前3行数据
    
                       A         B         C         D
    2017-01-01 -0.520856 -0.555019 -2.286424  1.745681
    2017-01-02  1.114030  0.861933  0.795958  0.420670
    2017-01-03 -0.343605 -0.937356  0.052693 -0.540735
    2017-01-04  1.587684 -0.743756  0.021738 -0.702190
    2017-01-05  1.243403  0.930299  0.234343  1.604182
    ------------------------------------------------------------
                       A         B         C         D
    2017-01-05  1.243403  0.930299  0.234343  1.604182
    2017-01-06 -0.087004 -0.368055  1.434022  0.464193
    2017-01-07 -1.248981  0.973724 -0.288384 -0.577388
    

    查看索引,列和底层numpy数据(行,列,值)

    df.index     # 查看行索引
    df.columns   # 查看列字段
    df.values    # 查看数据
    
    DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
                   '2017-01-05', '2017-01-06', '2017-01-07'],
                  dtype='datetime64[ns]', freq='D')
    
    Index(['A', 'B', 'C', 'D'], dtype='object')
    
    [[ 2.23820398  0.18440123  0.08039084 -0.27751926]
     [-0.12335513  0.36641304 -0.28617579  0.34383109]
     [-0.85403491  0.63876989  1.26032173 -1.27382333]
     [-0.07262661 -0.01788962  0.28748668  1.12715561]
     [-1.14293392 -0.88263364  0.72250762 -1.64051326]
     [ 0.41864083  0.40545953 -0.14591541 -0.57168728]
     [ 1.01383531 -0.22793823 -0.44045634  1.04799829]]
    

    描述显示数据的快速统计摘要

    df.describe()
    
                  A         B         C         D
    count  7.000000  7.000000  7.000000  7.000000
    mean  -0.675425 -0.257835  0.144049  0.275621
    std    1.697957  0.793953  1.301520  1.412291
    min   -2.595040 -1.200401 -1.230538 -0.976166
    25%   -1.992393 -0.723464 -0.897041 -0.800919
    50%   -1.050666 -0.445612  0.004719 -0.705840
    75%    0.592677  0.068574  0.874195  1.398337
    max    1.717166  1.150948  2.279856  2.416514
    

    转置数据

    df.T
    
       2017-01-01  2017-01-02  2017-01-03  2017-01-04  2017-01-05  2017-01-06
    A    0.932454   -2.148503    1.398975    1.565676   -0.167527   -0.242041
    B    0.584585    1.373330   -0.069801   -0.102857    1.286432   -0.703491
    C   -0.345119   -0.680955    1.686750    1.184996    0.016170   -0.663963
    D    0.431751    0.444830   -1.524739    0.040007    0.220172    1.423627
    

    通过轴排序

    df.sort_index(axis=1, ascending=False)  # 横轴,ascending=False 从大到小,降序
    df.sort_index(axis=0, ascending=False)  # 纵轴
    
    # 横轴倒序,axis=1
    				D         C         B         A
    2017-01-01  0.426359  2.542352 -0.324047  0.418973
    2017-01-02 -0.834625 -1.356709  0.150744 -1.690500
    2017-01-03 -0.018274  0.900801  1.072851  0.149830
    2017-01-04 -1.075027 -0.889379 -0.663223 -1.404002
    2017-01-05 -1.273966 -1.335761 -1.356561 -1.135199
    2017-01-06 -1.590793  0.693430 -0.504164  0.143386
    
    # 纵轴倒序,axis=0
    				A			B			C			D
    2020-01-07	0.002582	-0.684076	-1.154203	-0.419264
    2020-01-06	0.040282	1.085169	0.156559	-0.843088
    2020-01-05	2.256867	1.329317	-0.660518	0.357097
    2020-01-04	-0.486968	-1.126489	-1.530925	-0.036522
    2020-01-03	-0.926477	-0.002553	-0.176788	1.867908
    2020-01-02	-1.775777	0.226779	1.918664	2.182794
    2020-01-01	-0.250033	0.426570	0.196574	2.200098
    

    按值排序

    df.sort_values(by='B')
    
                       A         B         C         D
    2017-01-06  0.764517 -1.526019  0.400456 -0.182082
    2017-01-05 -0.177845 -1.269836 -0.534676  0.796666
    2017-01-04 -0.981485 -0.082572 -1.272123  0.508929
    2017-01-02 -0.290117  0.053005 -0.295628 -0.346965
    2017-01-03  0.941131  0.799280  2.054011 -0.684088
    2017-01-01  0.597788  0.892008  0.903053 -0.821024
    

    选择区块

    选择一列,产生一个系列

    df.A
    df['A']
    
    2017-01-01    0.317460
    2017-01-02   -0.933726
    2017-01-03    0.167860
    2017-01-04    0.816184
    2017-01-05   -0.745503
    2017-01-06    0.505319
    Freq: D, Name: A, dtype: float64
    

    选择通过[]操作符,选择切片行

    df[0:3]  # 通过索引,取左不取右
    
    df['20170102':'20170103']  # 通过索引名称,取左右边界
    
                       A         B         C         D
    2017-01-01  1.103449  0.926571 -1.649978 -0.309270
    2017-01-02  0.516404 -0.734076 -0.081163 -0.528497
    2017-01-03  0.240356  0.231224 -1.463315 -1.157256
    
                       A         B         C         D
    2017-01-02  0.516404 -0.734076 -0.081163 -0.528497
    2017-01-03  0.240356  0.231224 -1.463315 -1.157256
    

    loc 通过索引名称取一行

    df.loc[dates[0]]
    
    A   -0.483292
    B   -0.536987
    C   -0.889947
    D    1.250857
    Name: 2017-01-01 00:00:00, dtype: float64
    

    loc 通过标签名称选择多行多列,取左右边界

    df.loc[:,['A','B']]  # 所有行,AB两列
    df.loc['20170102':'20170104',['A','B']]  # 02-04行,AB两列
    df.loc['20170102',['A','B']]  # 02一行,AB两列
    df.loc[dates[0],'A']  # dates[0]日期名称一行,A一列,即具体的标量值
    
                       A         B
    2017-01-01  0.479048 -0.105106
    2017-01-02  0.172920  0.086570
    2017-01-03 -1.302485 -0.593550
    2017-01-04 -0.595438  1.304054
    2017-01-05  0.154267  1.336219
    2017-01-06 -0.341204  0.781300
    
                       A         B
    2017-01-02  1.062995 -0.108277
    2017-01-03  1.962106 -0.294664
    2017-01-04 -0.128576  0.717738
    
    A    0.252749
    B    0.119747
    Name: 2017-01-02 00:00:00, dtype: float64
    
    -0.0839903627822
    

    at 通过行列名称快速访问标量(等同于先前的方法)

    df.at[dates[0],'A']
    
    -0.0839903627822
    

    iloc 通过行列index索引位置取一行

    df.iloc[3]
    
    A    0.944506
    B    1.035781
    C    0.421373
    D    0.017660
    Name: 2017-01-04 00:00:00, dtype: float64
    

    iloc 通过行列索引index位置切片,取多行多列

    df.iloc[3:5,0:2]
    df.iloc[1:3,:]
    df.iloc[:,1:3]
    df.iloc[1,1]  # 取第一行第一列,得到标量值
    
                       A         B
    2017-01-04 -1.617068  0.548090
    2017-01-05 -0.864247  0.419743
    

    iloc 通过行列索引index位置的列表,取几行几列

    df.iloc[[1,2,4],[0,2]])
    
                       A         C
    2017-01-02  0.085091  0.568128
    2017-01-03  0.729076 -0.451151
    2017-01-05 -1.281975 -0.190119
    

    iat 通过行列索引index位置快速访问标量(等同于先前的方法)

    df.iat[1,1]
    
    -0.170996002652
    

    布尔索引

    通过单列的值是否满足条件,来选择数据

    df[df.A > 0]  # A列的值大于0的数据
    
                       A         B         C         D
    2017-01-03  0.276486 -1.003779  0.721863 -0.558061
    2017-01-04  1.177206 -0.464778 -0.116442 -0.385712
    2017-01-06  0.846665 -1.398207 -0.145356  0.924342
    

    从满足布尔条件的DataFrame中选择值

    df[df > 0]
    
                       A         B         C         D
    2017-01-01       NaN  1.963213  0.643244  0.945643
    2017-01-02  0.364237  0.917368       NaN       NaN
    2017-01-03  0.702624       NaN  0.088565       NaN
    2017-01-04  1.274313       NaN  2.313910       NaN
    2017-01-05  2.586315  0.588273       NaN  1.482597
    2017-01-06       NaN  0.405928  0.309201       NaN
    

    使用isin()方法进行过滤

    df2 = df.copy()
    df2['E'] = ['one', 'one','two','three','four','three']
    df2[df2['E'].isin(['two','four'])]
    
                       A         B         C         D      E
    2017-01-01  0.723399 -0.369247  0.863941 -1.910875    one
    2017-01-02 -0.047573 -0.609780  2.130650 -0.019281    one
    2017-01-03 -0.566122 -0.850374 -0.031516  0.362023    two
    2017-01-04  0.903819 -0.513673  0.118850 -0.351811  three
    2017-01-05 -0.485232 -0.864457  1.396835 -1.696083   four
    2017-01-06  0.272145 -0.644449 -1.319063 -0.201354  three
    ============= start to filter =============== 
                       A         B         C         D     E
    2017-01-03 -0.566122 -0.850374 -0.031516  0.362023   two
    2017-01-05 -0.485232 -0.864457  1.396835 -1.696083  four
    

    如果使用IPython,则会自动启用列名(以及公共属性)的选项完成。 以下是将要完成的属性的一个子集:

    In [13]: df2.<TAB>
    df2.A                  df2.bool
    df2.abs                df2.boxplot
    df2.add                df2.C
    df2.add_prefix         df2.clip
    df2.add_suffix         df2.clip_lower
    df2.align              df2.clip_upper
    df2.all                df2.columns
    df2.any                df2.combine
    df2.append             df2.combine_first
    df2.apply              df2.compound
    df2.applymap           df2.consolidate
    df2.D
    

    可以看到,列ABCD自动标签完成。E也在一样。其余的属性为了简洁而被截短。

    //原文出自【易百教程】,商业转载请联系作者获得授权,非商业转载请保留原文链接:https://www.yiibai.com/pandas/python_pandas_series.html

    DataFrame 操作

    pandas.DataFrame( data, index, columns, dtype, copy)
    
    参数 描述
    data 数据,如:ndarrayseriesmaplistdictconstant和另一个DataFrame
    index 缺省值np.arrange(n)
    columns 缺省值np.arrange(n)
    dtype 每列的数据类型
    copy 如果默认值为False,用于复制数据。

    创建DataFrame

    DataFrame 可以使用各种输入创建 :

    • 列表
    • 字典
    • 系列
    • Numpy ndarrays
    • 另一个数据帧(DataFrame)

    创建一个空的DataFrame

    df = pd.DataFrame()
    

    从列表创建DataFrame

    data = [1,2,3,4,5]
    df = pd.DataFrame(data)
    
         0
    0    1
    1    2
    2    3
    3    4
    4    5
    
    data = [['Alex',10],['Bob',12],['Clarke',13]]
    df = pd.DataFrame(data,columns=['Name','Age'])
    df = pd.DataFrame(data,columns=['Name','Age'],dtype=float)  
    # dtype参数将Age列的类型更改为浮点。
    
          Name      Age
    0     Alex      10
    1     Bob       12
    2     Clarke    13
    
          Name     Age
    0     Alex     10.0
    1     Bob      12.0
    2     Clarke   13.0
    

    从ndarrays/Lists的字典来创建DataFrame

    所有的ndarrays必须具有相同的长度。如果传递了索引(index),则索引的长度应等于数组的长度。

    列表的长度必须一致,必要时用 np.nan 补全。

    data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,42]}
    data = {'Name':['Tom', 'Jack', 'Steve', 'Ricky'],'Age':[28,34,29,np.nan]}
    df = pd.DataFrame(data, index=['rank1','rank2','rank3','rank4'])
    
          Age      Name
    0     28        Tom
    1     34       Jack
    2     29      Steve
    3     42      Ricky
    
             Age    Name
    rank1    28      Tom
    rank2    34     Jack
    rank3    29    Steve
    rank4    42    Ricky
    

    从列表创建数据帧DataFrame

    字典列表可作为输入数据传递以用来创建数据帧(DataFrame),字典键默认为列名。

    data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
    # NaN被填充到key缺失的区域。
    df = pd.DataFrame(data)
    df = pd.DataFrame(data, index=['first', 'second'])
    
        a    b      c
    0   1   2     NaN
    1   5   10   20.0
    
            a   b       c
    first   1   2     NaN
    second  5   10   20.0
    
    data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
    df1 = pd.DataFrame(data, index=['first', 'second'], columns=['a', 'b'])
    df2 = pd.DataFrame(data, index=['first', 'second'], columns=['a', 'b1'])
    
             a  b
    first    1  2
    second   5  10
    
             a  b1
    first    1  NaN
    second   5  NaN
    

    从系列的字典来创建DataFrame

    字典的系列可以传递以形成一个DataFrame。 所得到的索引是通过的所有系列索引的并集。

    d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
          'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}
    df = pd.DataFrame(d)
    
          one    two
    a     1.0    1
    b     2.0    2
    c     3.0    3
    d     NaN    4
    

    添加列

    # 跟字典有点像
    df['three']=pd.Series([10,20,30],index=['a','b','c'])
    df['four']=df['one']+df['three']
    # np.nan + 1 = nan
    

    删除列

    del df['one']
    df.pop('two')
    

    添加行

    df = df.append(df2)
    

    df['bbb']= [1,'2', 3,3,3]

    0       int64
    aaa     int64
    bbb    object
    dtype: object
    

    df.iloc[2,1].dtype

    dtype('int64')
    

    删除行

    使用索引标签从DataFrame中删除或删除行。 如果标签重复,则会删除多行。

    df = df.drop(0)
    

    panel

    面板(Panel)是3D容的数据。面板数据一词来源于计量经济学,部分源于名称:Pandas - pan(el)-da(ta)-s

    3轴(axis)这个名称旨在给出描述涉及面板数据的操作的一些语义。它们是 -

    • items - axis 0,每个项目对应于内部包含的数据帧(DataFrame)。
    • major_axis - axis 1,它是每个数据帧(DataFrame)的索引行。
    • minor_axis - axis 2,它是每个数据帧(DataFrame)的索引列。

    Panel 操作

    可以使用以下构造函数创建面板 -

    pandas.Panel(data, items, major_axis, minor_axis, dtype, copy)
    

    构造函数的参数如下 -

    参数 描述
    data 数据采取各种形式,如:ndarrayseriesmaplistsdictconstant和另一个数据帧(DataFrame)
    items axis=0
    major_axis axis=1
    minor_axis axis=2
    dtype 每列的数据类型
    copy 复制数据,默认 - false

    2. 创建面板

    • 从ndarrays创建
    • 从DataFrames的dict创建

    2.1 从3D ndarray创建

    data = np.random.rand(2,4,5)
    p = pd.Panel(data)
    
    <class 'pandas.core.panel.Panel'>
    Dimensions: 2 (items) x 4 (major_axis) x 5 (minor_axis)
    Items axis: 0 to 1
    Major_axis axis: 0 to 3
    Minor_axis axis: 0 to 4
    

    2.2 从DataFrame对象的dict创建面板

    data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 
            'Item2' : pd.DataFrame(np.random.randn(4, 2))}
    p = pd.Panel(data)
    
    <class 'pandas.core.panel.Panel'>
    Dimensions: 2 (items) x 4 (major_axis) x 5 (minor_axis)
    Items axis: 0 to 1
    Major_axis axis: 0 to 3
    Minor_axis axis: 0 to 4
    

    2.3 创建一个空面板

    p = pd.Panel()
    
    <class 'pandas.core.panel.Panel'>
    Dimensions: 0 (items) x 0 (major_axis) x 0 (minor_axis)
    Items axis: None
    Major_axis axis: None
    Minor_axis axis: None
    

    3. 从面板中选择数据

    要从面板中选择数据,可以使用以下方式 -

    • Items
    • Major_axis
    • Minor_axis

    使用Items

    data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 
            'Item2' : pd.DataFrame(np.random.randn(4, 2))}
    p = pd.Panel(data)
    print p['Item1']
    
                0          1          2
    0    0.488224  -0.128637   0.930817
    1    0.417497   0.896681   0.576657
    2   -2.775266   0.571668   0.290082
    3   -0.400538  -0.144234   1.110535
    

    使用major_axis

    # creating an empty panel
    import pandas as pd
    import numpy as np
    data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 
            'Item2' : pd.DataFrame(np.random.randn(4, 2))}
    p = pd.Panel(data)
    print p.major_xs(1)
    

    执行上面示例代码,得到以下结果 -

          Item1       Item2
    0   0.417497    0.748412
    1   0.896681   -0.557322
    2   0.576657       NaN
    

    使用minor_axis

    data = {'Item1' : pd.DataFrame(np.random.randn(4, 3)), 
            'Item2' : pd.DataFrame(np.random.randn(4, 2))}
    p = pd.Panel(data)
    print p.minor_xs(1)
    

    执行上面示例代码,得到以下结果 -

           Item1       Item2
    0   -0.128637   -1.047032
    1    0.896681   -0.557322
    2    0.571668    0.431953
    3   -0.144234    1.302466
    

    Series 基本功能

    属性或方法 描述
    axes 返回轴标签列表
    dtype 返回对象的数据类型(dtype)
    empty 如果系列为空,则返回True
    ndim 返回底层数据的维数,默认定义:1
    size 返回基础数据中的元素数
    values 将系列作为ndarray返回
    head() 返回前n
    tail() 返回最后n

    DataFrame 基本功能

    下面来看看数据帧(DataFrame)的基本功能有哪些?下表列出了DataFrame基本功能的重要属性或方法。

    属性或方法 描述
    T 转置
    axes 行轴标签和列轴标签
    dtypes 每一列的类型
    empty 完全为空,则返回为True,否则False
    ndim 维度大小
    shape 返回表示DataFrame的维度的元组
    size NDFrame中的元素数
    values NDFrame的Numpy表示
    head() 返回开头前n
    tail() 返回最后n

    描述性统计

    DataFrame聚合函数,轴可以通过名称或整数来指定:

    • 数据帧(DataFrame) : “index”(axis=0,默认),columns(axis=1)

    axis=1 实例

    df.sum(1)
    

    pandas 数据类型分为:数字类型和object。object即python对象,字符串等。

    str 不能与 数字 相加。通常一列的类型相同。也可以不同,但是不科学。

    函数

    编号 函数 描述
    1 count() 非空数量
    2 sum() 所有值之和
    3 mean() 所有值的平均值
    4 median() 所有值的中位数
    5 mode() 值的模值
    6 std() 值的标准偏差
    7 min() 所有值中的最小值
    8 max() 所有值中的最大值
    9 abs() 绝对值
    10 prod() 数组元素的乘积
    11 cumsum() 累计总和
    12 cumprod() 累计乘积

    注 - 由于DataFrame是异构数据结构。通用操作不适用于所有函数。

    • 类似于:sum()cumsum()函数能与数字和字符(或)字符串数据元素一起工作,不会产生任何错误。字符聚合从来都比较少被使用,虽然这些函数不会引发任何异常。
    • 由于这样的操作无法执行,因此,当DataFrame包含字符或字符串数据时,像abs()cumprod()这样的函数会抛出异常。

    汇总数据

    describe()函数是用来计算有关DataFrame列的统计信息的摘要。

    df.describe()
    
                   Age         Rating
    count    12.000000      12.000000
    mean     31.833333       3.743333
    std       9.232682       0.661628
    min      23.000000       2.560000
    25%      25.000000       3.230000
    50%      29.500000       3.790000
    75%      35.500000       4.132500
    max      51.000000       4.800000
    

    该函数给出了平均值,标准差和IQR值。 而且,函数排除字符列,并给出关于数字列的摘要。 include是用于传递关于什么列需要考虑用于总结的必要信息的参数。获取值列表; 默认情况下是”数字值”。

    • object - 汇总字符串列
    • number - 汇总数字列
    • all - 将所有列汇总在一起(不应将其作为列表值传递)

    现在,在程序中使用以下语句并检查输出 -

    df.describe(include=['object'])
    

    表格函数应用

    • 表合理函数应用:pipe()
    • 行或列函数应用:apply()
    • 元素函数应用:applymap()

    DataFrame中的所有元素相加一个值2

    def adder(ele1,ele2):
       return ele1+ele2
    
    df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
    df = df.pipe(adder,2)
    

    行或列合理函数应用

    可以使用apply()方法沿DataFramePanel的轴应用任意函数。 默认情况下,操作按列执行,将每列列为数组。

    df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
    df = df.apply(np.mean)
    

    通过传递axis参数,可以在行上执行操作。

    df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
    df = df.apply(np.mean,axis=1)
    

    元素合理函数应用

    并不是所有的函数都可以向量化(也不是返回另一个数组的NumPy数组,也不是任何值),在DataFrame上的方法applymap()和类似于在Series上的map()接受任何Python函数,并且返回单个值。

    map :让一行执行函数
    df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
    df = df['col1'].map(lambda x:x*100)
    
    0     14.439581
    1    163.536125
    2     88.995853
    3    -31.210458
    4    -73.832149
    
    applymap : 每一个值都执行函数
    df = pd.DataFrame(np.random.randn(5,3),columns=['col1','col2','col3'])
    df = df.applymap(lambda x:x*100)
    

    重建索引

    可以通过索引来实现多个操作

    • 重新排序现有数据以匹配一组新的标签。
    • 在没有标签数据的标签位置插入缺失值(NA)标记。

    reindex 重建索引

    N=20
    
    df = pd.DataFrame({
       'A': pd.date_range(start='2016-01-01',periods=N,freq='D'),
       'x': np.linspace(0,stop=N-1,num=N),
       'y': np.random.rand(N),
       'C': np.random.choice(['Low','Medium','High'],N).tolist(),
       'D': np.random.normal(100, 10, size=(N)).tolist()
    })
    
    df_reindexed = df.reindex(index=[0,2,5], columns=['A', 'C', 'B'])
    

    执行上面示例代码,得到以下结果 -

                A    C     B
    0  2016-01-01  Low   NaN
    2  2016-01-03  High  NaN
    5  2016-01-06  Low   NaN
    

    reindex_like 重建索引与其他对象对齐

    有时可能希望采取一个对象和重新索引,其轴被标记为与另一个对象相同。

    df1 = pd.DataFrame(np.random.randn(10,3),columns=['col1','col2','col3'])
    df2 = pd.DataFrame(np.random.randn(7,3),columns=['col1','col2','col3'])
    
    df1 = df1.reindex_like(df2)
    
              col1         col2         col3
    0    -2.467652    -1.211687    -0.391761
    1    -0.287396     0.522350     0.562512
    2    -0.255409    -0.483250     1.866258
    3    -1.150467    -0.646493    -0.222462
    4     0.152768    -2.056643     1.877233
    5    -1.155997     1.528719    -1.343719
    6    -1.015606    -1.245936    -0.295275
    

    填充时重新加注

    reindex()采用可选参数方法,它是一个填充方法,其值如下:

    • pad/ffill - 向前填充值
    • bfill/backfill - 向后填充值
    • nearest - 从最近的索引值填充
    df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3'])
    df2 = pd.DataFrame(np.random.randn(2,3),columns=['col1','col2','col3'])
    
    print df2.reindex_like(df1)
    print df2.reindex_like(df1,method='ffill')
    

    执行上面示例代码时,得到以下结果 -

             col1        col2       col3
    0    1.311620   -0.707176   0.599863
    1   -0.423455   -0.700265   1.133371
    2         NaN         NaN        NaN
    3         NaN         NaN        NaN
    4         NaN         NaN        NaN
    5         NaN         NaN        NaN
    
    Data Frame with Forward Fill:
             col1        col2        col3
    0    1.311620   -0.707176    0.599863
    1   -0.423455   -0.700265    1.133371
    2   -0.423455   -0.700265    1.133371
    3   -0.423455   -0.700265    1.133371
    4   -0.423455   -0.700265    1.133371
    5   -0.423455   -0.700265    1.133371
    

    注 - 最后四行被填充了。

    重建索引时的填充限制

    限制参数在重建索引时提供对填充的额外控制。限制指定连续匹配的最大计数。

    df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3'])
    df2 = pd.DataFrame(np.random.randn(2,3),columns=['col1','col2','col3'])
    
    print df2.reindex_like(df1)
    print df2.reindex_like(df1,method='ffill',limit=1)
    

    在执行上面示例代码时,得到以下结果 -

             col1        col2        col3
    0    0.247784    2.128727    0.702576
    1   -0.055713   -0.021732   -0.174577
    2         NaN         NaN         NaN
    3         NaN         NaN         NaN
    4         NaN         NaN         NaN
    5         NaN         NaN         NaN
    
    Data Frame with Forward Fill limiting to 1:
             col1        col2        col3
    0    0.247784    2.128727    0.702576
    1   -0.055713   -0.021732   -0.174577
    2   -0.055713   -0.021732   -0.174577
    3         NaN         NaN         NaN
    4         NaN         NaN         NaN
    5         NaN         NaN         NaN
    

    注意 - 只有一行被填充。 然后,其它行按原样保留。

    重命名

    rename()方法允许基于一些映射(字典或者系列)或任意函数来重新标记一个轴。

    rename()方法提供了一个inplace命名参数,默认为False并复制底层数据。 指定传递inplace = True则表示将数据本身重命名。

    df1 = pd.DataFrame(np.random.randn(6,3),columns=['col1','col2','col3'])
    print df1.rename(columns={'col1' : 'c1', 'col2' : 'c2'},
    index = {0 : 'apple', 1 : 'banana', 2 : 'durian'})
    
             col1        col2        col3
    0    0.486791    0.105759    1.540122
    1   -0.990237    1.007885   -0.217896
    2   -0.483855   -1.645027   -1.194113
    3   -0.122316    0.566277   -0.366028
    4   -0.231524   -0.721172   -0.112007
    5    0.438810    0.000225    0.435479
    
                    c1          c2        col3
    apple     0.486791    0.105759    1.540122
    banana   -0.990237    1.007885   -0.217896
    durian   -0.483855   -1.645027   -1.194113
    3        -0.122316    0.566277   -0.366028
    4        -0.231524   -0.721172   -0.112007
    5         0.438810    0.000225    0.435479
    

    迭代

    Pandas对象之间的基本迭代的行为取决于类型。当迭代一个系列时,它被视为数组式,基本迭代产生这些值。其他数据结构,如:DataFramePanel,遵循类似惯例迭代对象的键。

    简而言之,基本迭代(对于i在对象中)产生

    • Series - 值

    • DataFrame - 列标签

    • Pannel - 项目标签

    迭代DataFrame

    迭代DataFrame提供列名。现在来看看下面的例子来理解这个概念。

    for col in df:  # 列标签
       print (col)
    

    执行上面示例代码,得到以下结果 -

    A
    C
    D
    x
    y
    

    要遍历数据帧(DataFrame)中的行,可以使用以下函数

    • iteritems() - 迭代(列,列值)
    • iterrows() - 将行迭代为(行索引,行值)对
    • itertuples() - 以namedtuples的形式迭代行

    iteritems()示例

    列作为键,列值迭代为Series对象

    df = pd.DataFrame(np.random.randn(4,3),columns=['col1','col2','col3'])
    for key,value in df.iteritems():
       print (key,value)
    
    col1 0    0.802390
    1    0.324060
    2    0.256811
    3    0.839186
    Name: col1, dtype: float64
    
    col2 0    1.624313
    1   -1.033582
    2    1.796663
    3    1.856277
    Name: col2, dtype: float64
    
    col3 0   -0.022142
    1   -0.230820
    2    1.160691
    3   -0.830279
    Name: col3, dtype: float64
    Shell
    

    iterrows()示例

    iterrows()返回迭代器,产生每个索引值以及包含每行数据的序列。

    df = pd.DataFrame(np.random.randn(4,3),columns = ['col1','col2','col3'])
    for row_index,row in df.iterrows():
       print (row_index,row)
    
    0  col1    1.529759
       col2    0.762811
       col3   -0.634691
    Name: 0, dtype: float64
    
    1  col1   -0.944087
       col2    1.420919
       col3   -0.507895
    Name: 1, dtype: float64
    
    2  col1   -0.077287
       col2   -0.858556
       col3   -0.663385
    Name: 2, dtype: float64
    3  col1    -1.638578
       col2     0.059866
       col3     0.493482
    Name: 3, dtype: float64
    Shell
    

    注意 - 由于iterrows()遍历行,因此不会跨该行保留数据类型。0,1,2是行索引,col1col2col3是列索引。

    itertuples()示例

    itertuples()方法将为DataFrame中的每一行返回一个产生一个命名元组的迭代器。元组的第一个元素将是行的相应索引值,而剩余的值是行值。

    df = pd.DataFrame(np.random.randn(4,3),columns = ['col1','col2','col3'])
    for row in df.itertuples():
        print (row)
    
    Pandas(Index=0, col1=1.5297586201375899, col2=0.76281127433814944, col3=-
    0.6346908238310438)
    
    Pandas(Index=1, col1=-0.94408735763808649, col2=1.4209186418359423, col3=-
    0.50789517967096232)
    
    Pandas(Index=2, col1=-0.07728664756791935, col2=-0.85855574139699076, col3=-
    0.6633852507207626)
    
    Pandas(Index=3, col1=0.65734942534106289, col2=-0.95057710432604969,
    col3=0.80344487462316527)
    Shell
    

    注意 - 不要尝试在迭代时修改任何对象。迭代是用于读取,迭代器返回原始对象(视图)的副本,因此更改将不会反映在原始对象上。

    df = pd.DataFrame(np.random.randn(4,3),columns = ['col1','col2','col3'])
    for index, row in df.iterrows():
       row['a'] = 10
    print (df)
    

    执行上面示例代码,得到以下结果 -

            col1       col2       col3
    0  -1.739815   0.735595  -0.295589
    1   0.635485   0.106803   1.527922
    2  -0.939064   0.547095   0.038585
    3  -1.016509  -0.116580  -0.523158
    

    注意观察结果,修改变化并未反映出来。

    排序

    Pandas有两种排序方式:

    • 按标签
    • 按实际值

    按标签排序

    # axis 默认为0,即按照行索引排序;1按照列排序。默认升序。
    sorted_df=unsorted_df.sort_index()
    # ascending=False:按照降序;反之,正序。
    sorted_df=unsorted_df.sort_index(ascending=False,axis=1)
    

    按值排序

    # 通过by参数指定需要列值
    sorted_df = un_df.sort_values(by='col1')
    sorted_df = un_df.sort_values(by=['col1','col2'])
    sorted_df=un_df.sort_values(by=['col1'],ascending=False)
    

    排序算法

    sort_values()提供了:mergeesortheapsortquicksort中选择算法的一个配置。Mergesort是唯一稳定的算法。

    sorted_df=unsorted_df.sort_values(by='col1',kind='mergesort')
    

    字符串和文本数据

    Pandas提供了一组字符串函数,可以方便地对字符串数据进行操作。 最重要的是,这些函数忽略(或排除)丢失/NaN值。

    几乎这些方法都使用Python字符串函数(请参阅: http://docs.python.org/3/library/stdtypes.html#string-methods )。 因此,将Series对象转换为String对象,然后执行函数。

    函数 描述
    lower() Series/Index中的字符串转换为小写。
    upper() Series/Index中的字符串转换为大写。
    len() 计算字符串长度。
    strip() 帮助从两侧的系列/索引中的每个字符串中删除空格(包括换行符)。
    split(' ') 用给定的模式拆分每个字符串。
    cat(sep=' ') 使用给定的分隔符连接系列/索引元素。
    get_dummies() 返回具有单热编码值的数据帧(DataFrame)。
    contains(pattern) 如果元素中包含子字符串,则返回每个元素的布尔值True,否则为False
    replace(a,b) 将值a替换为值b
    repeat(value) 重复每个元素指定的次数。
    count(pattern) 返回模式中每个元素的出现总数。
    startswith(pattern) 如果系列/索引中的元素以模式开始,则返回true
    endswith(pattern) 如果系列/索引中的元素以模式结束,则返回true
    find(pattern) 返回模式第一次出现的位置。
    findall(pattern) 返回模式的所有出现的列表。
    swapcase 变换字母大小写。
    islower() 检查系列/索引中每个字符串中的所有字符是否小写,返回布尔值
    isupper() 检查系列/索引中每个字符串中的所有字符是否大写,返回布尔值
    isnumeric() 检查系列/索引中每个字符串中的所有字符是否为数字,返回布尔值。
    s.str.lower()
    s.str.upper()
    s.str.swapcase()
    s.str.islower()
    s.str.isupper()
    s.str.isnumeric()
    s.str.len()
    s.str.strip()
    s.str.split(' ')
    s.str.replace('@','$')
    s.str.count('m')
    
    s.str.cat(sep=' <=> ')
    # Tom  <=>  William Rick <=> John <=> Alber@t
    s.str.get_dummies()
    """
        William Rick  Alber@t  John  Tom 
    0              0        0     0     1
    1              1        0     0     0
    2              0        0     1     0
    3              0        1     0     0
    """
    s.str.contains(' ')
    """
    0     True
    1     True
    2    False
    3    False
    dtype: bool
    """
    s.str.repeat(2)
    """
    0                      Tom Tom 
    1     William Rick William Rick
    2                      JohnJohn
    3                Alber@tAlber@t
    dtype: object
    """
    s.str.find('e')  # 第一个匹配的索引,-1表示元素中没有这样的模式可用。
    """
    0   -1
    1   -1
    2   -1
    3    3
    dtype: int64
    """
    s.str.findall('e')  # 找到所有的匹配列表,空列表([])表示元素中没有这样的模式可用。
    """
    0     []
    1     []
    2     []
    3    [e]
    dtype: object
    """
    

    Pandas选项和自定义

    Pandas提供API来自定义其行为的某些方面,大多使用来显示。

    API由五个相关函数组成。

    • get_option()
    • set_option()
    • reset_option()
    • describe_option()
    • option_context()

    get_option(param)

    获取如下值:

    display.max_rows

    显示上限的行

    print(pd.get_option("display.max_rows"))
    

    display.max_columns

    显示上限的列

    print (pd.get_option("display.max_columns")
    

    set_option(param,value)

    设置如下的值:

    使用set_option(),可以更改要显示的默认行数。

    pd.set_option("display.max_rows",80)
    pd.set_option("display.max_columns",32)
    

    reset_option(param)

    display.max_rows

    重置如下值为默认值:

    pd.reset_option("display.max_rows")
    

    describe_option(param)

    打印如下值参数的描述。

    pd.describe_option("display.max_rows")
    

    option_context()

    option_context上下文管理器用于临时设置语句中的选项。当退出使用块时,选项值将自动恢复。

    # 临时设置该值,退出代码块临时值不生效
    with pd.option_context("display.max_rows",10):
       print(pd.get_option("display.max_rows"))
    print(pd.get_option("display.max_rows"))
    

    常用参数:

    编号 参数 描述
    1 display.max_rows 要显示的最大行数
    2 display.max_columns 要显示的最大列数
    3 display.expand_frame_repr 显示数据帧以拉伸页面
    4 display.max_colwidth 显示最大列宽
    5 display.precision 显示十进制数的精度

    选择数据

    编号 索引 描述
    1 .loc() 基于标签
    2 .iloc() 基于整数
    3 .ix() 基于标签和整数

    .loc()

    包括起始边界。整数是有效的标签,但它们是指标签而不是位置。

    print (df.loc[:,'A'])
    print (df.loc[:,['A','C']])
    print (df.loc['a':'h'])
    print (df.loc['a']>0)
    

    .iloc()

    print (df.iloc[:4])
    print (df.iloc[1:5, 2:4])
    print (df.iloc[[1, 3, 5], [1, 3]])
    

    .ix()

    除了基于纯标签和整数之外,Pandas还提供了一种使用.ix()运算符进行选择和子集化对象的混合方法。

    print (df.ix[:4])
    
              A         B         C         D
    0 -1.449975 -0.002573  1.349962  0.539765
    1 -1.249462 -0.800467  0.483950  0.187853
    2  1.361273 -1.893519  0.307613 -0.119003
    3 -0.103433 -1.058175 -0.587307 -0.114262
    4 -0.612298  0.873136 -0.607457  1.047772
    
    print (df.ix[:,'A'])
    

    使用符号

    使用多轴索引从Pandas对象获取值可使用以下符号 -

    对象 索引 描述
    Series s.loc[indexer] 标量值
    DataFrame df.loc[row_index,col_index] 标量对象
    Panel p.loc[item_index,major_index, minor_index] p.loc[item_index,major_index, minor_index]

    注意 - .iloc().ix()应用相同的索引选项和返回值。

    现在来看看如何在DataFrame对象上执行每个操作。这里使用基本索引运算符[]

    print (df['A'])
    
    print (df[2:2])
    
    Empty DataFrame
    Columns: [A, B, C, D]
    Index: []
    

    属性访问

    可以使用属性运算符.来选择列。

    print (df.A)
    

    统计函数

    统计方法有助于理解和分析数据的行为。现在我们将学习一些统计函数,可以将这些函数应用到Pandas的对象上。

    pct_change()函数

    系列,DatFrames和Panel都有pct_change()函数。此函数将每个元素与其前一个元素进行比较,并计算变化百分比。

    import pandas as pd
    import numpy as np
    s = pd.Series([1,2,3,4,5,4])
    print (s.pct_change())
    
    df = pd.DataFrame(np.random.randn(5, 2))
    print (df.pct_change())
    Python
    

    执行上面示例代码,得到以下结果 -

    0        NaN
    1   1.000000
    2   0.500000
    3   0.333333
    4   0.250000
    5  -0.200000
    dtype: float64
    
                0          1
    0         NaN        NaN
    1  -15.151902   0.174730
    2  -0.746374   -1.449088
    3  -3.582229   -3.165836
    4   15.601150  -1.860434
    Shell
    

    默认情况下,pct_change()对列进行操作; 如果想应用到行上,那么可使用axis = 1参数。

    协方差

    协方差适用于系列数据。Series对象有一个方法cov用来计算序列对象之间的协方差。NA将被自动排除。

    Cov系列示例

    import pandas as pd
    import numpy as np
    s1 = pd.Series(np.random.randn(10))
    s2 = pd.Series(np.random.randn(10))
    print (s1.cov(s2))
    Python
    

    执行上面示例代码,得到以下结果 -

    0.0667296739178
    Python
    

    当应用于DataFrame时,协方差方法计算所有列之间的协方差(cov)值。

    import pandas as pd
    import numpy as np
    frame = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e'])
    print (frame['a'].cov(frame['b']))
    print (frame.cov())
    Python
    

    执行上面示例代码,得到以下结果 -

    -0.406796939839
              a         b         c         d         e
    a  0.784886 -0.406797  0.181312  0.513549 -0.597385
    b -0.406797  0.987106 -0.662898 -0.492781  0.388693
    c  0.181312 -0.662898  1.450012  0.484724 -0.476961
    d  0.513549 -0.492781  0.484724  1.571194 -0.365274
    e -0.597385  0.388693 -0.476961 -0.365274  0.785044
    Shell
    

    注 - 观察第一个语句中ab列之间的cov结果值,与由DataFrame上的cov返回的值相同。

    相关性

    相关性显示了任何两个数值(系列)之间的线性关系。有多种方法来计算pearson(默认),spearmankendall之间的相关性。

    import pandas as pd
    import numpy as np
    frame = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e'])
    
    print (frame['a'].corr(frame['b']))
    print (frame.corr())
    Python
    

    执行上面示例代码,得到以下结果 -

    -0.613999376618
              a         b         c         d         e
    a  1.000000 -0.613999 -0.040741 -0.227761 -0.192171
    b -0.613999  1.000000  0.012303  0.273584  0.591826
    c -0.040741  0.012303  1.000000 -0.391736 -0.470765
    d -0.227761  0.273584 -0.391736  1.000000  0.364946
    e -0.192171  0.591826 -0.470765  0.364946  1.000000
    Shell
    

    如果DataFrame中存在任何非数字列,则会自动排除。

    数据排名

    数据排名为元素数组中的每个元素生成排名。在关系的情况下,分配平均等级。

    import pandas as pd
    import numpy as np
    s = pd.Series(np.random.randn(5), index=list('abcde'))
    
    s['d'] = s['b'] # so there's a tie
    
    print (s.rank())
    Python
    

    执行上面示例代码,得到以下结果 -

    a    4.0
    b    1.5
    c    3.0
    d    1.5
    e    5.0
    dtype: float64
    Shell
    

    Rank可选地使用一个默认为true的升序参数; 当错误时,数据被反向排序,也就是较大的值被分配较小的排序。

    Rank支持不同的tie-breaking方法,用方法参数指定 -

    • average - 并列组平均排序等级
    • min - 组中最低的排序等级
    • max - 组中最高的排序等级
    • first - 按照它们出现在数组中的顺序分配队列

    Pandas窗口函数

    为了处理数字数据,Pandas提供了几个变体,如滚动,展开和指数移动窗口统计的权重。 其中包括总和,均值,中位数,方差,协方差,相关性等。

    下来学习如何在DataFrame对象上应用上提及的每种方法。

    .rolling()函数

    这个函数可以应用于一系列数据。指定window=n参数并在其上应用适当的统计函数。

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(10, 4),
    index = pd.date_range('1/1/2020', periods=10),
    columns = ['A', 'B', 'C', 'D'])
    
    print (df.rolling(window=3).mean())
    Python
    

    执行上面示例代码,得到以下结果 -

                       A         B         C         D
    2020-01-01       NaN       NaN       NaN       NaN
    2020-01-02       NaN       NaN       NaN       NaN
    2020-01-03 -0.306293  0.214001 -0.076004 -0.200793
    2020-01-04  0.236632 -0.437033  0.046111 -0.252062
    2020-01-05  0.761818 -0.181635 -0.546929 -0.738482
    2020-01-06  1.306498 -0.411834 -0.680948 -0.070285
    2020-01-07  0.956877 -0.749315 -0.503484  0.160620
    2020-01-08  0.354319 -1.067165 -1.238036  1.051048
    2020-01-09  0.262081 -0.898373 -1.059351  0.342291
    2020-01-10  0.326801 -0.350519 -1.064437  0.749869
    Shell
    

    注 - 由于窗口大小为3(window),前两个元素有空值,第三个元素的值将是nn-1n-2元素的平均值。这样也可以应用上面提到的各种函数了。

    .expanding()函数

    这个函数可以应用于一系列数据。 指定min_periods = n参数并在其上应用适当的统计函数。

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(10, 4),
          index = pd.date_range('1/1/2018', periods=10),
          columns = ['A', 'B', 'C', 'D'])
    print (df.expanding(min_periods=3).mean())
    Python
    

    执行上面示例代码得到以下结果 -

                       A         B         C         D
    2018-01-01       NaN       NaN       NaN       NaN
    2018-01-02       NaN       NaN       NaN       NaN
    2018-01-03 -0.425085 -0.124270 -0.324134 -0.234001
    2018-01-04 -0.293824 -0.038188 -0.172855  0.447226
    2018-01-05 -0.516146 -0.013441 -0.384935  0.379267
    2018-01-06 -0.614905  0.290308 -0.594635  0.414396
    2018-01-07 -0.606090  0.121265 -0.604148  0.246296
    2018-01-08 -0.597291  0.075374 -0.425182  0.092831
    2018-01-09 -0.380505  0.074956 -0.253081  0.146426
    2018-01-10 -0.235030  0.018936 -0.259566  0.315200
    Shell
    

    .ewm()函数

    ewm()可应用于系列数据。指定comspanhalflife参数,并在其上应用适当的统计函数。它以指数形式分配权重。

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(10, 4),
       index = pd.date_range('1/1/2019', periods=10),
       columns = ['A', 'B', 'C', 'D'])
    print (df.ewm(com=0.5).mean())
    Python
    

    执行上面示例函数,得到以下结果 -

                       A         B         C         D
    2019-01-01  1.047165  0.777385 -1.286948 -0.080564
    2019-01-02  0.484093 -0.630998 -0.975172 -0.117832
    2019-01-03  0.056189  0.830492  0.116325  1.005547
    2019-01-04 -0.363824  1.222173  0.497901 -0.235209
    2019-01-05 -0.260685  1.066029  0.391480  1.196190
    2019-01-06  0.389649  1.458152 -0.231936 -0.481003
    2019-01-07  1.071035 -0.016003  0.387420 -0.170811
    2019-01-08 -0.573686  1.052081  1.218439  0.829366
    2019-01-09  0.222927  0.556430  0.811838 -0.562096
    2019-01-10  0.224624 -1.225446  0.204961 -0.800444
    Shell
    

    窗口函数主要用于通过平滑曲线来以图形方式查找数据内的趋势。如果日常数据中有很多变化,并且有很多数据点可用,那么采样和绘图就是一种方法,应用窗口计算并在结果上绘制图形是另一种方法。 通过这些方法,可以平滑曲线或趋势。

    Pandas聚合

    当有了滚动,扩展和ewm对象创建了以后,就有几种方法可以对数据执行聚合。

    DataFrame应用聚合

    让我们创建一个DataFrame并在其上应用聚合。

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(10, 4),
          index = pd.date_range('1/1/2019', periods=10),
          columns = ['A', 'B', 'C', 'D'])
    
    print (df)
    print("=======================================")
    r = df.rolling(window=3,min_periods=1)
    print (r)
    Python
    

    执行上面示例代码,得到以下结果 -

                       A         B         C         D
    2019-01-01 -0.901602 -1.778484  0.728295 -0.758108
    2019-01-02 -0.826162  0.994140  0.976164 -0.918249
    2019-01-03  0.260841  0.905993  1.505967 -0.124883
    2019-01-04 -0.112230 -0.111885  0.702712 -0.871768
    2019-01-05 -0.239969  1.435918 -0.160140 -0.547702
    2019-01-06 -0.126897 -2.628206 -0.280658  0.167422
    2019-01-07  0.367903  0.994337 -0.529830  0.195990
    2019-01-08 -0.530872 -0.384915 -0.397150 -0.024074
    2019-01-09 -0.418925  0.049046 -0.816616  0.308107
    2019-01-10 -0.176857  2.573145  0.010211 -1.427078
    =======================================
    Rolling [window=3,min_periods=1,center=False,axis=0]
    Shell
    

    可以通过向整个DataFrame传递一个函数来进行聚合,或者通过标准的获取项目方法来选择一个列。

    在整个数据框上应用聚合

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(10, 4),
          index = pd.date_range('1/1/2000', periods=10),
          columns = ['A', 'B', 'C', 'D'])
    print df
    
    r = df.rolling(window=3,min_periods=1)
    print r.aggregate(np.sum)
    Python
    

    执行示例代码,得到以下结果 -

                       A         B         C         D
    2020-01-01  1.069090 -0.802365 -0.323818 -1.994676
    2020-01-02  0.190584  0.328272 -0.550378  0.559738
    2020-01-03  0.044865  0.478342 -0.976129  0.106530
    2020-01-04 -1.349188 -0.391635 -0.292740  1.412755
    2020-01-05  0.057659 -1.331901 -0.297858 -0.500705
    2020-01-06  2.651680 -1.459706 -0.726023  0.294283
    2020-01-07  0.666481  0.679205 -1.511743  2.093833
    2020-01-08 -0.284316 -1.079759  1.433632  0.534043
    2020-01-09  1.115246 -0.268812  0.190440 -0.712032
    2020-01-10 -0.121008  0.136952  1.279354  0.275773
    ============================================
                       A         B         C         D
    2020-01-01  1.069090 -0.802365 -0.323818 -1.994676
    2020-01-02  1.259674 -0.474093 -0.874197 -1.434938
    2020-01-03  1.304539  0.004249 -1.850326 -1.328409
    2020-01-04 -1.113739  0.414979 -1.819248  2.079023
    2020-01-05 -1.246664 -1.245194 -1.566728  1.018580
    2020-01-06  1.360151 -3.183242 -1.316621  1.206333
    2020-01-07  3.375821 -2.112402 -2.535624  1.887411
    2020-01-08  3.033846 -1.860260 -0.804134  2.922160
    2020-01-09  1.497411 -0.669366  0.112329  1.915845
    2020-01-10  0.709922 -1.211619  2.903427  0.097785
    Shell
    

    在数据框的单个列上应用聚合

    示例代码

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(10, 4),
          index = pd.date_range('1/1/2000', periods=10),
          columns = ['A', 'B', 'C', 'D'])
    print (df)
    print("====================================")
    r = df.rolling(window=3,min_periods=1)
    print (r['A'].aggregate(np.sum))
    Python
    

    执行上面示例代码,得到以下结果 -

                       A         B         C         D
    2000-01-01 -1.095530 -0.415257 -0.446871 -1.267795
    2000-01-02 -0.405793 -0.002723  0.040241 -0.131678
    2000-01-03 -0.136526  0.742393 -0.692582 -0.271176
    2000-01-04  0.318300 -0.592146 -0.754830  0.239841
    2000-01-05 -0.125770  0.849980  0.685083  0.752720
    2000-01-06  1.410294  0.054780  0.297992 -0.034028
    2000-01-07  0.463223 -1.239204 -0.056420  0.440893
    2000-01-08 -2.244446 -0.516937 -2.039601 -0.680606
    2000-01-09  0.991139  0.026987 -2.391856  0.585565
    2000-01-10  0.112228 -0.701284 -1.139827  1.484032
    ====================================
    2000-01-01   -1.095530
    2000-01-02   -1.501323
    2000-01-03   -1.637848
    2000-01-04   -0.224018
    2000-01-05    0.056004
    2000-01-06    1.602824
    2000-01-07    1.747747
    2000-01-08   -0.370928
    2000-01-09   -0.790084
    2000-01-10   -1.141079
    Freq: D, Name: A, dtype: float64
    Shell
    

    在DataFrame的多列上应用聚合

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(10, 4),
          index = pd.date_range('1/1/2018', periods=10),
          columns = ['A', 'B', 'C', 'D'])
    print (df)
    print ("==========================================")
    r = df.rolling(window=3,min_periods=1)
    print (r[['A','B']].aggregate(np.sum))
    Python
    

    执行上面示例代码,得到以下结果 -

                       A         B         C         D
    2018-01-01  0.518897  0.988917  0.435691 -1.005703
    2018-01-02  1.793400  0.130314  2.313787  0.870057
    2018-01-03 -0.297601  0.504137 -0.951311 -0.146720
    2018-01-04  0.282177  0.142360 -0.059013  0.633174
    2018-01-05  2.095398 -0.153359  0.431514 -1.185657
    2018-01-06  0.134847  0.188138  0.828329 -1.035120
    2018-01-07  0.780541  0.138942 -1.001229  0.714896
    2018-01-08  0.579742 -0.642858  0.835013 -1.504110
    2018-01-09 -1.692986 -0.861327 -1.125359  0.006687
    2018-01-10 -0.263689  1.182349 -0.916569  0.617476
    ==========================================
                       A         B
    2018-01-01  0.518897  0.988917
    2018-01-02  2.312297  1.119232
    2018-01-03  2.014697  1.623369
    2018-01-04  1.777976  0.776811
    2018-01-05  2.079975  0.493138
    2018-01-06  2.512422  0.177140
    2018-01-07  3.010786  0.173722
    2018-01-08  1.495130 -0.315777
    2018-01-09 -0.332703 -1.365242
    2018-01-10 -1.376932 -0.321836
    Shell
    

    在DataFrame的单个列上应用多个函数

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(10, 4),
          index = pd.date_range('2019/01/01', periods=10),
          columns = ['A', 'B', 'C', 'D'])
    print (df)
    
    print("==========================================")
    
    r = df.rolling(window=3,min_periods=1)
    print (r['A'].aggregate([np.sum,np.mean]))
    Python
    

    执行上面示例代码,得到以下结果 -

                       A         B         C         D
    2019-01-01  1.022641 -1.431910  0.780941 -0.029811
    2019-01-02 -0.302858  0.009886 -0.359331 -0.417708
    2019-01-03 -1.396564  0.944374 -0.238989 -1.873611
    2019-01-04  0.396995 -1.152009 -0.560552 -0.144212
    2019-01-05 -2.513289 -1.085277 -1.016419 -1.586994
    2019-01-06 -0.513179  0.823411  0.670734  1.196546
    2019-01-07 -0.363239 -0.991799  0.587564 -1.100096
    2019-01-08  1.474317  1.265496 -0.216486 -0.224218
    2019-01-09  2.235798 -1.381457 -0.950745 -0.209564
    2019-01-10 -0.061891 -0.025342  0.494245 -0.081681
    ==========================================
                     sum      mean
    2019-01-01  1.022641  1.022641
    2019-01-02  0.719784  0.359892
    2019-01-03 -0.676780 -0.225593
    2019-01-04 -1.302427 -0.434142
    2019-01-05 -3.512859 -1.170953
    2019-01-06 -2.629473 -0.876491
    2019-01-07 -3.389707 -1.129902
    2019-01-08  0.597899  0.199300
    2019-01-09  3.346876  1.115625
    2019-01-10  3.648224  1.216075
    Shell
    

    在DataFrame的多列上应用多个函数

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(10, 4),
          index = pd.date_range('2020/01/01', periods=10),
          columns = ['A', 'B', 'C', 'D'])
    
    print (df)
    print("==========================================")
    r = df.rolling(window=3,min_periods=1)
    print (r[['A','B']].aggregate([np.sum,np.mean]))
    Python
    

    执行上面示例代码,得到以下结果 -

                       A         B         C         D
    2020-01-01  1.053702  0.355985  0.746638 -0.233968
    2020-01-02  0.578520 -1.171843 -1.764249 -0.709913
    2020-01-03 -0.491185  0.975212  0.200139 -3.372621
    2020-01-04 -1.331328  0.776316  0.216623  0.202313
    2020-01-05 -1.023147 -0.913686  1.457512  0.999232
    2020-01-06  0.995328 -0.979826 -1.063695  0.057925
    2020-01-07  0.576668  1.065767 -0.270744 -0.513707
    2020-01-08  0.520258  0.969043 -0.119177 -0.125620
    2020-01-09 -0.316480  0.549085  1.862249  1.091265
    2020-01-10  0.461321 -0.368662 -0.988323  0.543011
    ==========================================
                       A                   B          
                     sum      mean       sum      mean
    2020-01-01  1.053702  1.053702  0.355985  0.355985
    2020-01-02  1.632221  0.816111 -0.815858 -0.407929
    2020-01-03  1.141037  0.380346  0.159354  0.053118
    2020-01-04 -1.243993 -0.414664  0.579686  0.193229
    2020-01-05 -2.845659 -0.948553  0.837843  0.279281
    2020-01-06 -1.359146 -0.453049 -1.117195 -0.372398
    2020-01-07  0.548849  0.182950 -0.827744 -0.275915
    2020-01-08  2.092254  0.697418  1.054985  0.351662
    2020-01-09  0.780445  0.260148  2.583896  0.861299
    2020-01-10  0.665099  0.221700  1.149466  0.383155
    Shell
    

    将不同的函数应用于DataFrame的不同列

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(3, 4),
          index = pd.date_range('2020/01/01', periods=3),
          columns = ['A', 'B', 'C', 'D'])
    print (df)
    print("==========================================")
    r = df.rolling(window=3,min_periods=1)
    print (r.aggregate({'A' : np.sum,'B' : np.mean}))
    Python
    

    执行上面示例代码,得到以下结果 -

                       A         B         C         D
    2020-01-01 -0.246302 -0.057202  0.923807 -1.019698
    2020-01-02  0.285287  1.467206 -0.368735 -0.397260
    2020-01-03 -0.163219 -0.401368  1.254569  0.580188
    ==========================================
                       A         B
    2020-01-01 -0.246302 -0.057202
    2020-01-02  0.038985  0.705002
    2020-01-03 -0.124234  0.336212
    

    Pandas缺失数据

    数据丢失(缺失)在现实生活中总是一个问题。 机器学习和数据挖掘等领域由于数据缺失导致的数据质量差,在模型预测的准确性上面临着严重的问题。 在这些领域,缺失值处理是使模型更加准确和有效的重点。

    何时以及为什么数据丢失?

    想象一下有一个产品的在线调查。很多时候,人们不会分享与他们有关的所有信息。 很少有人分享他们的经验,但不是他们使用产品多久; 很少有人分享使用产品的时间,经验,但不是他们的个人联系信息。 因此,以某种方式或其他方式,总会有一部分数据总是会丢失,这是非常常见的现象。

    如何处理使用Pandas的缺失值(如NANaN)。

    检测缺失值

    isnull()notnull()函数,是Series和DataFrame对象的方法

    df['one'].isnull()
    df['one'].notnull()
    

    缺少数据的计算

    • 在求和数据时,NA将被视为0
    • 如果数据全部是NA,那么结果将是NA
    df['one'].sum()
    

    清理/填充缺少数据

    用标量值替换NaN

    df.fillna(0)  # 用0替换NAN, 当然,也可以填充任何其他的值。
    

    根据前面或后面的值填充NAN

    方法 动作
    pad/fill 根据前面填充
    bfill/backfill 根据后面填充
    df.fillna(method='pad')
    df.fillna(method='backfill')
    df.fillna(method='backfill',axis=1)
    

    删除缺少的值

    如果只想排除缺少的值,则使用dropna函数和axis参数。 默认情况下,axis = 0,即在行上应用,这意味着如果行内的任何值是NA,那么整个行被排除。

    df.dropna()
    df.dropna(axis=1)
    

    替换丢失(或)通用值

    用标量值替换NAfillna()函数的等效行为。

    df.replace({1000:10,2000:60})  # 把1000和2000分别替换为10,60
    print(df.replace({np.nan:100000}))
    

    分组(GroupBy)

    任何分组(groupby)操作都涉及原始对象的以下操作之一。它们是 -

    • 分割对象
    • 应用一个函数
    • 结合的结果

    在许多情况下,我们将数据分成多个集合,并在每个子集上应用一些函数。在应用函数中,可以执行以下操作

    • 聚合 - 计算汇总统计
    • 转换 - 执行一些特定于组的操作
    • 过滤 - 在某些情况下丢弃数据

    DataFrame对象所有操作

    将数据拆分成组

    Pandas对象可以分成任何对象。

    • obj.groupby(‘key’)
    • obj.groupby([‘key1’,’key2’])
    • obj.groupby(key,axis=1)
    df.groupby('Team')
    
    <pandas.core.groupby.DataFrameGroupBy object at 0x00000245D60AD518>
    

    查看分组

    df.groupby('Team').groups
    
    {
    'Devils': Int64Index([2, 3], dtype='int64'), 
    'Kings': Int64Index([4, 6, 7], dtype='int64'), 
    'Riders': Int64Index([0, 1, 8, 11], dtype='int64'), 
    'Royals': Int64Index([9, 10], dtype='int64'), 
    'kings': Int64Index([5], dtype='int64')
    }
    

    按多列分组

    df.groupby(['Team','Year']).groups
    
    {
    ('Devils', 2014): Int64Index([2], dtype='int64'), 
    ('Devils', 2015): Int64Index([3], dtype='int64'), 
    ('Kings', 2014): Int64Index([4], dtype='int64'),
    ('Kings', 2016): Int64Index([6], dtype='int64'),
    ('Kings', 2017): Int64Index([7], dtype='int64'), 
    ('Riders', 2014): Int64Index([0], dtype='int64'), 
    ('Riders', 2015): Int64Index([1], dtype='int64'), 
    ('Riders', 2016): Int64Index([8], dtype='int64'), 
    ('Riders', 2017): Int64Index([11], dtype='int64'),
    ('Royals', 2014): Int64Index([9], dtype='int64'), 
    ('Royals', 2015): Int64Index([10], dtype='int64'), 
    ('kings', 2015): Int64Index([5], dtype='int64')
    }
    

    迭代遍历分组

    使用groupby对象,可以遍历类似itertools.obj的对象。

    grouped = df.groupby('Year')
    
    for name,group in grouped:
        print (name)
        print (group)
    

    执行上面示例代码,得到以下结果 -

    2014
       Points  Rank    Team  Year
    0     876     1  Riders  2014
    2     863     2  Devils  2014
    4     741     3   Kings  2014
    9     701     4  Royals  2014
    2015
        Points  Rank    Team  Year
    1      789     2  Riders  2015
    3      673     3  Devils  2015
    5      812     4   kings  2015
    10     804     1  Royals  2015
    

    默认情况下,groupby对象具有与分组名相同的标签名称。

    选择一个分组

    使用get_group()方法,可以选择一个组。参考以下示例代码 -

    grouped = df.groupby('Year')
    grouped.get_group(2014)
    
       Points  Rank    Team  Year
    0     876     1  Riders  2014
    2     863     2  Devils  2014
    4     741     3   Kings  2014
    9     701     4  Royals  2014
    

    聚合

    聚合函数为每个组返回单个聚合值。当创建了分组(group by)对象,就可以对分组数据执行多个聚合操作。

    一个比较常用的是通过聚合或等效的agg方法聚合

    grouped = df.groupby('Year')
    grouped['Points'].agg(np.mean)
    
    Year
    2014    795.25
    2015    769.50
    2016    725.00
    2017    739.00
    Name: Points, dtype: float64
    

    另一种查看每个分组的大小的方法是应用size()函数

    grouped = df.groupby('Team')
    grouped.agg(np.size)
    
    Team                      
    Devils       2     2     2
    Kings        3     3     3
    Riders       4     4     4
    Royals       2     2     2
    kings        1     1     1
    

    一次应用多个聚合函数

    通过分组系列,还可以传递函数的列表或字典来进行聚合,并生成DataFrame作为输出 -

    grouped = df.groupby('Team')
    agg = grouped['Points'].agg([np.sum, np.mean, np.std])
    
             sum        mean         std
    Team                                
    Devils  1536  768.000000  134.350288
    Kings   2285  761.666667   24.006943
    Riders  3049  762.250000   88.567771
    Royals  1505  752.500000   72.831998
    kings    812  812.000000         NaN
    

    转换

    分组或列上的转换返回索引大小与被分组的索引相同的对象。因此,转换应该返回与组块大小相同的结果。

    grouped = df.groupby('Team')
    score = lambda x: (x - x.mean()) / x.std()*10
    grouped.transform(score)
    
           Points       Rank       Year
    0   12.843272 -15.000000 -11.618950
    1    3.020286   5.000000  -3.872983
    2    7.071068  -7.071068  -7.071068
    3   -7.071068   7.071068   7.071068
    4   -8.608621  11.547005 -10.910895
    5         NaN        NaN        NaN
    6   -2.360428  -5.773503   2.182179
    7   10.969049  -5.773503   8.728716
    8   -7.705963   5.000000   3.872983
    9   -7.071068   7.071068  -7.071068
    10   7.071068  -7.071068   7.071068
    11  -8.157595   5.000000  11.618950
    

    过滤

    过滤根据定义的标准过滤数据并返回数据的子集。filter()函数用于过滤数据。

    filter = df.groupby('Team').filter(lambda x: len(x) >= 3)
    
        Points  Rank    Team  Year
    0      876     1  Riders  2014
    1      789     2  Riders  2015
    4      741     3   Kings  2014
    6      756     1   Kings  2016
    7      788     1   Kings  2017
    8      694     2  Riders  2016
    11     690     2  Riders  2017
    

    Pandas合并/连接

    Pandas具有功能全面的高性能内存中连接操作,与SQL等关系数据库非常相似。
    Pandas提供了一个单独的merge()函数,作为DataFrame对象之间所有标准数据库连接操作的入口

    pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
    left_index=False, right_index=False, sort=True)
    

    在这里,有以下几个参数可以使用 -

    • left - 一个DataFrame对象。
    • right - 另一个DataFrame对象。
    • on - 列(名称)连接,必须在左和右DataFrame对象中存在(找到)。
    • left_on - 左侧DataFrame中的列用作键,可以是列名或长度等于DataFrame长度的数组。
    • right_on - 右侧的DataFrame的列作为键,可以是列名或长度等于DataFrame长度的数组。
    • left_index - 如果为True,则使用左侧DataFrame中的索引(行标签)作为其连接键。 在具有MultiIndex(分层)的DataFrame的情况下,级别的数量必须与来自右DataFrame的连接键的数量相匹配。
    • right_index - 与右DataFrame的left_index具有相同的用法。
    • how - 它是left, right, outer以及inner之中的一个,默认为内inner。 下面将介绍每种方法的用法。
    • sort - 按照字典顺序通过连接键对结果DataFrame进行排序。默认为True,设置为False时,在很多情况下大大提高性能。

    在一个键上合并两个数据帧

    rs = pd.merge(left,right,on='id')
    

    合并多个键上的两个数据框

    rs = pd.merge(left,right,on=['id','subject_id'])
    

    合并使用“how”的参数

    如果组合键没有出现在左侧或右侧表中,则连接表中的值将为NA

    合并方法 SQL等效 描述
    left LEFT OUTER JOIN 使用左侧对象的键
    right RIGHT OUTER JOIN 使用右侧对象的键
    outer FULL OUTER JOIN 使用键的联合
    inner INNER JOIN 使用键的交集
    rs = pd.merge(left, right, on='subject_id', how='left')
    rs = pd.merge(left, right, on='subject_id', how='right')
    rs = pd.merge(left, right, how='outer', on='subject_id')
    rs = pd.merge(left, right, on='subject_id', how='inner')
    

    Pandas级联

    Pandas提供了各种工具(功能),可以轻松地将SeriesDataFramePanel对象组合在一起。

    pd.concat(objs,axis=0,join='outer',join_axes=None,
    ignore_index=False)
    

    其中,

    • objs - 这是Series,DataFrame或Panel对象的序列或映射。
    • axis - {0,1,...},默认为0,这是连接的轴。
    • join - {'inner', 'outer'},默认inner。如何处理其他轴上的索引。联合的外部和交叉的内部。
    • ignore_index − 布尔值,默认为False。如果指定为True,则不要使用连接轴上的索引值。结果轴将被标记为:0,...,n-1
    • join_axes - 这是Index对象的列表。用于其他(n-1)轴的特定索引,而不是执行内部/外部集逻辑。

    连接对象

    concat()函数完成了沿轴执行级联操作的所有重要工作。下面代码中,创建不同的对象并进行连接。

    import pandas as pd
    one = pd.DataFrame({
             'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
             'subject_id':['sub1','sub2','sub4','sub6','sub5'],
             'Marks_scored':[98,90,87,69,78]},
             index=[1,2,3,4,5])
    two = pd.DataFrame({
             'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
             'subject_id':['sub2','sub4','sub3','sub6','sub5'],
             'Marks_scored':[89,80,79,97,88]},
             index=[1,2,3,4,5])
    rs = pd.concat([one,two])
    print(rs)
    
       Marks_scored    Name subject_id
    1            98    Alex       sub1
    2            90     Amy       sub2
    3            87   Allen       sub4
    4            69   Alice       sub6
    5            78  Ayoung       sub5
    1            89   Billy       sub2
    2            80   Brian       sub4
    3            79    Bran       sub3
    4            97   Bryce       sub6
    5            88   Betty       sub5
    

    假设想把特定的键与每个碎片的DataFrame关联起来。可以通过使用键参数来实现这一点 -

    import pandas as pd
    one = pd.DataFrame({
             'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
             'subject_id':['sub1','sub2','sub4','sub6','sub5'],
             'Marks_scored':[98,90,87,69,78]},
             index=[1,2,3,4,5])
    two = pd.DataFrame({
             'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
             'subject_id':['sub2','sub4','sub3','sub6','sub5'],
             'Marks_scored':[89,80,79,97,88]},
             index=[1,2,3,4,5])
    rs = pd.concat([one,two],keys=['x','y'])
    print(rs)
    
         Marks_scored    Name subject_id
    x 1            98    Alex       sub1
      2            90     Amy       sub2
      3            87   Allen       sub4
      4            69   Alice       sub6
      5            78  Ayoung       sub5
    y 1            89   Billy       sub2
      2            80   Brian       sub4
      3            79    Bran       sub3
      4            97   Bryce       sub6
      5            88   Betty       sub5
    

    结果的索引是重复的; 每个索引重复。如果想要生成的对象必须遵循自己的索引,请将ignore_index设置为True。参考以下示例代码

    import pandas as pd
    one = pd.DataFrame({
             'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
             'subject_id':['sub1','sub2','sub4','sub6','sub5'],
             'Marks_scored':[98,90,87,69,78]},
             index=[1,2,3,4,5])
    two = pd.DataFrame({
             'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
             'subject_id':['sub2','sub4','sub3','sub6','sub5'],
             'Marks_scored':[89,80,79,97,88]},
             index=[1,2,3,4,5])
    rs = pd.concat([one,two],keys=['x','y'],ignore_index=True)
    
    print(rs)
    Python
    

    执行上面示例代码,得到以下结果 -

       Marks_scored    Name subject_id
    0            98    Alex       sub1
    1            90     Amy       sub2
    2            87   Allen       sub4
    3            69   Alice       sub6
    4            78  Ayoung       sub5
    5            89   Billy       sub2
    6            80   Brian       sub4
    7            79    Bran       sub3
    8            97   Bryce       sub6
    9            88   Betty       sub5
    

    观察,索引完全改变,键也被覆盖。如果需要沿axis=1添加两个对象,则会添加新列。

    import pandas as pd
    one = pd.DataFrame({
             'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
             'subject_id':['sub1','sub2','sub4','sub6','sub5'],
             'Marks_scored':[98,90,87,69,78]},
             index=[1,2,3,4,5])
    two = pd.DataFrame({
             'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
             'subject_id':['sub2','sub4','sub3','sub6','sub5'],
             'Marks_scored':[89,80,79,97,88]},
             index=[1,2,3,4,5])
    rs = pd.concat([one,two],axis=1)
    print(rs)
    

    执行上面示例代码,得到以下结果 -

       Marks_scored    Name subject_id  Marks_scored   Name subject_id
    1            98    Alex       sub1            89  Billy       sub2
    2            90     Amy       sub2            80  Brian       sub4
    3            87   Allen       sub4            79   Bran       sub3
    4            69   Alice       sub6            97  Bryce       sub6
    5            78  Ayoung       sub5            88  Betty       sub5
    

    使用附加连接

    连接的一个有用的快捷方式是在Series和DataFrame实例的append方法。这些方法实际上早于concat()方法。 它们沿axis=0连接,即索引

    import pandas as pd
    one = pd.DataFrame({
             'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
             'subject_id':['sub1','sub2','sub4','sub6','sub5'],
             'Marks_scored':[98,90,87,69,78]},
             index=[1,2,3,4,5])
    two = pd.DataFrame({
             'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
             'subject_id':['sub2','sub4','sub3','sub6','sub5'],
             'Marks_scored':[89,80,79,97,88]},
             index=[1,2,3,4,5])
    rs = one.append(two)
    print(rs)
    
       Marks_scored    Name subject_id
    1            98    Alex       sub1
    2            90     Amy       sub2
    3            87   Allen       sub4
    4            69   Alice       sub6
    5            78  Ayoung       sub5
    1            89   Billy       sub2
    2            80   Brian       sub4
    3            79    Bran       sub3
    4            97   Bryce       sub6
    5            88   Betty       sub5
    

    append()函数也可以带多个对象

    import pandas as pd
    
    one = pd.DataFrame({
             'Name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung'],
             'subject_id':['sub1','sub2','sub4','sub6','sub5'],
             'Marks_scored':[98,90,87,69,78]},
             index=[1,2,3,4,5])
    
    two = pd.DataFrame({
             'Name': ['Billy', 'Brian', 'Bran', 'Bryce', 'Betty'],
             'subject_id':['sub2','sub4','sub3','sub6','sub5'],
             'Marks_scored':[89,80,79,97,88]},
             index=[1,2,3,4,5])
    rs = one.append([two,one,two])
    print(rs)
    

    执行上面示例代码,得到以下结果 -

       Marks_scored    Name subject_id
    1            98    Alex       sub1
    2            90     Amy       sub2
    3            87   Allen       sub4
    4            69   Alice       sub6
    5            78  Ayoung       sub5
    1            89   Billy       sub2
    2            80   Brian       sub4
    3            79    Bran       sub3
    4            97   Bryce       sub6
    5            88   Betty       sub5
    1            98    Alex       sub1
    2            90     Amy       sub2
    3            87   Allen       sub4
    4            69   Alice       sub6
    5            78  Ayoung       sub5
    1            89   Billy       sub2
    2            80   Brian       sub4
    3            79    Bran       sub3
    4            97   Bryce       sub6
    5            88   Betty       sub5
    

    时间序列

    Pandas为时间序列数据的工作时间提供了一个强大的工具,尤其是在金融领域。在处理时间序列数据时,我们经常遇到以下情况

    • 生成时间序列
    • 将时间序列转换为不同的频率

    Pandas提供了一个相对紧凑和自包含的工具来执行上述任务。

    获取当前时间(pd将移除该方法,应该使用datetime)

    pd.datetime.now()
    
    2017-11-03 02:17:45.997992
    

    创建一个时间戳

    时间戳数据是时间序列数据的最基本类型,它将数值与时间点相关联。 对于Pandas对象来说,意味着使用时间点。

    time = pd.Timestamp('2018-11-01')
    
    2018-11-01 00:00:00
    

    也可以转换整数或浮动时期。这些的默认单位是纳秒。

    time = pd.Timestamp(1588686880,unit='s')
    
    2020-05-05 13:54:40
    

    创建一个时间范围

    # 默认频率为 D,time 是取time部分
    time = pd.date_range("12:00", "23:59", freq="30min").time  
    
    [datetime.time(12, 0) datetime.time(12, 30) datetime.time(13, 0)
     datetime.time(13, 30) datetime.time(14, 0) datetime.time(14, 30)
     datetime.time(15, 0) datetime.time(15, 30) datetime.time(16, 0)
     datetime.time(16, 30) datetime.time(17, 0) datetime.time(17, 30)
     datetime.time(18, 0) datetime.time(18, 30) datetime.time(19, 0)
     datetime.time(19, 30) datetime.time(20, 0) datetime.time(20, 30)
     datetime.time(21, 0) datetime.time(21, 30) datetime.time(22, 0)
     datetime.time(22, 30) datetime.time(23, 0) datetime.time(23, 30)]
    

    改变时间的频率

    time = pd.date_range("12:00", "23:59", freq="H").time
    
    [datetime.time(12, 0) datetime.time(13, 0) datetime.time(14, 0)
     datetime.time(15, 0) datetime.time(16, 0) datetime.time(17, 0)
     datetime.time(18, 0) datetime.time(19, 0) datetime.time(20, 0)
     datetime.time(21, 0) datetime.time(22, 0) datetime.time(23, 0)]
    

    转换为时间戳

    要转换类似日期的对象(例如字符串,时代或混合)的序列或类似列表的对象,可以使用to_datetime函数。当传递时将返回一个Series(具有相同的索引),而类似列表被转换为DatetimeIndex。 看看下面的例子 -

    time = pd.to_datetime(pd.Series(['Jul 31, 2009','2019-10-10', None]))
    
    0   2009-07-31
    1   2019-10-10
    2          NaT
    dtype: datetime64[ns]
    

    NaT表示不是一个时间的值(相当于NaN)

    time = pd.to_datetime(['2009/11/23', '2019.12.31', None])
    
    DatetimeIndex(['2009-11-23', '2019-12-31', 'NaT'], dtype='datetime64[ns]', freq=None)
    

    Pandas日期功能

    日期功能扩展了时间序列,在财务数据分析中起主要作用。在处理日期数据的同时,我们经常会遇到以下情况

    • 生成日期序列
    • 将日期序列转换为不同的频率

    创建一个日期范围

    通过指定周期和频率,使用date.range()函数就可以创建日期序列。 默认情况下,范围的频率是天。

    datelist = pd.date_range('2020/11/21', periods=5)
    
    DatetimeIndex(['2020-11-21', '2020-11-22', '2020-11-23', '2020-11-24',
                   '2020-11-25'],
                  dtype='datetime64[ns]', freq='D')
    

    更改日期频率

    datelist = pd.date_range('2020/11/21', periods=5,freq='M')
    
    DatetimeIndex(['2020-11-30', '2020-12-31', '2021-01-31', '2021-02-28',
                   '2021-03-31'],
                  dtype='datetime64[ns]', freq='M')
    

    bdate_range()函数

    bdate_range()用来表示商业日期范围,不同于date_range(),它不包括星期六和星期天。

    datelist = pd.bdate_range('2011/11/03', periods=7)
    

    date_rangebdate_range这样的便利函数利用了各种频率别名。date_range的默认频率是日历中的自然日,而bdate_range的默认频率是工作日。

    start = pd.datetime(2017, 11, 1)
    end = pd.datetime(2017, 11, 5)
    dates = pd.date_range(start, end)
    
    DatetimeIndex(['2017-11-01', '2017-11-02', '2017-11-03', '2017-11-04',
                   '2017-11-05'],
                  dtype='datetime64[ns]', freq='D')
    

    偏移别名

    大量的字符串别名被赋予常用的时间序列频率。我们把这些别名称为偏移别名。

    别名 描述说明
    B 工作日频率
    BQS 商务季度开始频率
    D 日历/自然日频率
    A 年度(年)结束频率
    W 每周频率
    BA 商务年底结束
    M 月结束频率
    BAS 商务年度开始频率
    SM 半月结束频率
    BH 商务时间频率
    SM 半月结束频率
    BH 商务时间频率
    BM 商务月结束频率
    H 小时频率
    MS 月起始频率
    T, min 分钟的频率
    SMS SMS半开始频率
    S 秒频率
    BMS 商务月开始频率
    L, ms 毫秒
    Q 季度结束频率
    U, us 微秒
    BQ 商务季度结束频率
    N 纳秒
    BQ 商务季度结束频率
    QS 季度开始频率

    Pandas时间差(Timedelta)

    时间差(Timedelta)是时间上的差异,以不同的单位来表示。例如:日,小时,分钟,秒。它们可以是正值,也可以是负值。

    字符串

    通过传递字符串,可以创建一个timedelta对象。参考以下示例代码 -

    timediff = pd.Timedelta('2 days 2 hours 15 minutes 30 seconds')
    
    2 days 02:15:30
    

    整数

    通过传递一个整数值与指定单位,这样的一个参数也可以用来创建Timedelta对象。

    timediff = pd.Timedelta(6,unit='h')
    
    0 days 06:00:00
    

    数据偏移

    例如 - 周,天,小时,分钟,秒,毫秒,微秒,纳秒的数据偏移也可用于构建。

    timediff = pd.Timedelta(days=2)
    
    2 days 00:00:00
    

    运算操作

    可以在Series/DataFrames上执行运算操作,并通过在datetime64 [ns]系列或在时间戳上减法操作来构造timedelta64 [ns]系列。参考以下示例代码 -

    s = pd.Series(pd.date_range('2012-1-1', periods=3, freq='D'))
    td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ])
    df = pd.DataFrame(dict(A = s, B = td))
    
               A      B
    0 2012-01-01 0 days
    1 2012-01-02 1 days
    2 2012-01-03 2 days
    

    相加操作

    df['C']=df['A']+df['B']
    df.C = df.A-df.B  # 报错,不允许 点 . 
    
               A      B          C
    0 2018-01-01 0 days 2018-01-01
    1 2018-01-02 1 days 2018-01-03
    2 2018-01-03 2 days 2018-01-05
    

    相减操作

    df['D']=df['C']-df['B']
    
               A      B          C          D
    0 2018-01-01 0 days 2018-01-01 2018-01-01
    1 2018-01-02 1 days 2018-01-03 2018-01-02
    2 2018-01-03 2 days 2018-01-05 2018-01-03
    

    Pandas分类数据

    通常实时的数据包括重复的文本列。例如:性别,国家和代码等特征总是重复的。这些是分类数据的例子。

    分类变量只能采用有限的数量,而且通常是固定的数量。除了固定长度,分类数据可能有顺序,但不能执行数字操作。 分类是Pandas数据类型。

    分类数据类型在以下情况下非常有用

    • 一个字符串变量,只包含几个不同的值。将这样的字符串变量转换为分类变量将会节省一些内存。
    • 变量的词汇顺序与逻辑顺序("one""two""three")不同。 通过转换为分类并指定类别上的顺序,排序和最小/最大将使用逻辑顺序,而不是词法顺序。
    • 作为其他python库的一个信号,这个列应该被当作一个分类变量(例如,使用合适的统计方法或plot类型)。

    对象创建

    分类对象可以通过多种方式创建。类别/分类

    通过在pandas对象创建中将dtype指定为“category”

    s = pd.Series(["a","b","c","a"], dtype="category")
    
    0    a
    1    b
    2    c
    3    a
    dtype: category
    Categories (3, object): [a, b, c]
    

    传递给系列对象的元素数量是四个,但类别只有三个。观察相同的输出类别。

    pd.Categorical

    使用标准Pandas分类构造函数,我们可以创建一个类别对象。语法如下 -

    pandas.Categorical(values, categories, ordered)
    
    cat = pd.Categorical(['a', 'b', 'c', 'a', 'b', 'c'])
    
    [a, b, c, a, b, c]
    Categories (3, object): [a, b, c]
    
    cat = cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a'])
    
    [a, b, c, a, b, c, NaN]
    Categories (3, object): [c, b, a]
    

    这里,第二个参数表示类别。因此,在类别中不存在的任何值将被视为NaN

    cat = cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a'],ordered=True)
    
    [a, b, c, a, b, c, NaN]
    Categories (3, object): [c < b < a]
    

    从逻辑上讲,排序(ordered)意味着,a大于bb大于c

    描述

    使用分类数据上的.describe()命令,可以得到与类型字符串的Series或DataFrame类似的输出。

    cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
    df = pd.DataFrame({"cat":cat, "s":["a", "c", "c", np.nan]})
    print (df.describe())
    print ("=============================")
    print (df["cat"].describe())
    
           cat  s
    count    3  3
    unique   2  2
    top      c  c
    freq     2  2
    =============================
    count     3
    unique    2
    top       c
    freq      2
    Name: cat, dtype: object
    

    获取类别的属性

    obj.cat.categories命令用于获取对象的类别。

    s = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
    s.categories
    
    Index(['b', 'a', 'c'], dtype='object')
    

    obj.ordered命令用于获取对象的顺序。

    cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])
    cat.ordered
    
    False
    

    该函数返回结果为:False,因为这里没有指定任何顺序。

    重命名类别

    重命名类别是通过将新值分配给series.cat.categories属性来完成的。

    s = pd.Series(["a","b","c","a"], dtype="category")
    s.cat.categories = ["Group %s" % g for g in s.cat.categories]
    s.cat.categories
    
    s = pd.Categorical(['a','b','c','c'])
    s.categories = ['aaa %s'%g for g in s.categories]
    s.categories
    
    Index(['Group a', 'Group b', 'Group c'], dtype='object')
    

    初始类别[a,b,c]由对象的s.cat.categories属性更新。

    附加新类别
    使用Categorical.add.categories()方法,可以追加新的类别。

    s = pd.Series(["a","b","c","a"], dtype="category")
    s = s.cat.add_categories([4])
    s.cat.categories
    
    Index(['a', 'b', 'c', 4], dtype='object')
    

    删除类别
    使用Categorical.remove_categories()方法,可以删除不需要的类别。

    s.cat.remove_categories("a")
    

    执行上面示例代码,得到以下结果 -

    Original object:
    0    a
    1    b
    2    c
    3    a
    dtype: category
    Categories (3, object): [a, b, c]
    =====================================
    After removal:
    0    NaN
    1      b
    2      c
    3    NaN
    dtype: category
    Categories (2, object): [b, c]
    Shell
    

    分类数据的比较

    在三种情况下可以将分类数据与其他对象进行比较

    • 将等号(==!=)与类别数据相同长度的类似列表的对象(列表,系列,数组…)进行比较。
    • ordered==True和类别是相同时,所有比较(==!=>>=<,和<=)分类数据到另一个分类系列。
    • 将分类数据与标量进行比较。
    cat = pd.Series([1,2,3]).astype("category", categories=[1,2,3], ordered=True)
    cat1 = pd.Series([2,2,2]).astype("category", categories=[1,2,3], ordered=True)
    print (cat>cat1)
    
    0    False
    1    False
    2     True
    dtype: bool
    

    与分类比较:

    类不同,不能比较:

    Categoricals can only be compared if 'categories' are the same.

    大小未排序,只能比较相不相同,不能比:

    Unordered Categoricals can only compare equality or not

    与列表比较:

    长度相同:

    cat==[1,2,3]

    与标量比较:

    cat==5 # 可以

    cat>5 # 报错

    Cannot compare a Categorical for op gt with a scalar, which is not a category.

    Pandas可视化

    基本绘图:绘图

    Series和DataFrame上的这个功能只是使用matplotlib库的plot()方法的简单包装实现。

    df = pd.DataFrame(np.random.randn(10,4),index=pd.date_range('2018/12/18',
       periods=10), columns=list('ABCD'))
    df.plot()
    

    执行上面示例代码,得到以下结果 -

    img

    如果索引由日期组成,则调用gct().autofmt_xdate()来格式化x轴,如上图所示。

    我们可以使用xy关键字绘制一列与另一列。

    绘图方法允许除默认线图之外的少数绘图样式。 这些方法可以作为plot()kind关键字参数提供。这些包括

    • barbarh为条形
    • hist为直方图
    • boxplot为盒型图
    • area为“面积”
    • scatter为散点图

    条形图

    df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
    df.plot.bar()
    

    img

    要生成一个堆积条形图,通过指定:stacked=True

    df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
    df.plot.bar(stacked=True)
    

    img

    要获得水平条形图,使用barh()方法 -

    df = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
    df.plot.barh(stacked=True)
    

    执行上面示例代码,得到以下结果 -

    img

    直方图

    可以使用plot.hist()方法绘制直方图。我们可以指定bins的数量值。

    df = pd.DataFrame({'a':np.random.randn(1000)+1,'b':np.random.randn(1000),'c':
    np.random.randn(1000) - 1}, columns=['a', 'b', 'c'])
    df.plot.hist(bins=20)
    

    img

    要为每列绘制不同的直方图,请使用以下代码 -

    df=pd.DataFrame({'a':np.random.randn(1000)+1,'b':np.random.randn(1000),'c':
    np.random.randn(1000) - 1}, columns=['a', 'b', 'c'])
    df.hist(bins=20)
    

    img

    箱形图

    Boxplot可以绘制调用Series.box.plot()DataFrame.box.plot()DataFrame.boxplot()来可视化每列中值的分布。

    例如,这里是一个箱形图,表示对[0,1)上的统一随机变量的10次观察的五次试验。

    df = pd.DataFrame(np.random.rand(10, 5), columns=['A', 'B', 'C', 'D', 'E'])
    df.plot.box()
    

    img

    区域块图形

    可以使用Series.plot.area()DataFrame.plot.area()方法创建区域图形。

    df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd'])
    df.plot.area()
    

    执行上面示例代码,得到以下结果 -

    img

    散点图形

    可以使用DataFrame.plot.scatter()方法创建散点图。

    df = pd.DataFrame(np.random.rand(50, 4), columns=['a', 'b', 'c', 'd'])
    df.plot.scatter(x='a', y='b')
    

    img

    饼状图

    饼状图可以使用DataFrame.plot.pie()方法创建。

    df = pd.DataFrame(3 * np.random.rand(4), index=['a', 'b', 'c', 'd'], columns=['x'])
    df.plot.pie(subplots=True)
    

    img

    Pandas IO工具

    Pandas I/O API是一套像pd.read_csv()一样返回Pandas对象的顶级读取器函数。

    读取文本文件(或平面文件)的两个主要功能是read_csv()read_table()。它们都使用相同的解析代码来智能地将表格数据转换为DataFrame对象

    形式1

    pandas.read_csv(filepath_or_buffer, sep=',', delimiter=None, header='infer',
    names=None, index_col=None, usecols=None)
    

    形式2

    pandas.read_csv(filepath_or_buffer, sep='	', delimiter=None, header='infer',
    names=None, index_col=None, usecols=None)
    

    以下是csv文件数据的内容 -

    S.No,Name,Age,City,Salary
    1,Tom,28,Toronto,20000
    2,Lee,32,HongKong,3000
    3,Steven,43,Bay Area,8300
    4,Ram,38,Hyderabad,3900
    

    read.csv

    read.csv从csv文件中读取数据并创建一个DataFrame对象。

    import pandas as pd
    df=pd.read_csv("temp.csv")
    

    执行上面示例代码,得到以下结果 -

       S.No    Name  Age       City  Salary
    0     1     Tom   28    Toronto   20000
    1     2     Lee   32   HongKong    3000
    2     3  Steven   43   Bay Area    8300
    3     4     Ram   38  Hyderabad    3900
    

    自定义索引

    可以指定csv文件中的一列来使用index_col定制索引。

    df=pd.read_csv("temp.csv",index_col=['S.No'])
    

    执行上面示例代码,得到以下结果 -

            Name  Age       City  Salary
    S.No                                
    1        Tom   28    Toronto   20000
    2        Lee   32   HongKong    3000
    3     Steven   43   Bay Area    8300
    4        Ram   38  Hyderabad    3900
    

    转换器
    dtype的列可以作为字典传递。转换数据类型。

    df = pd.read_csv("temp.csv", dtype={'Salary': np.float64})
    print (df.dtypes)
    
    S.No        int64
    Name       object
    Age         int64
    City       object
    Salary    float64
    dtype: object
    

    默认情况下,Salary列的dtypeint,但结果显示为float,因为我们明确地转换了类型。

      S.No   Name   Age      City    Salary
    0   1     Tom   28    Toronto   20000.0
    1   2     Lee   32   HongKong    3000.0
    2   3  Steven   43   Bay Area    8300.0
    3   4     Ram   38  Hyderabad    3900.0
    

    header_names
    使用names参数指定标题的名称。

    df=pd.read_csv("temp.csv", names=['a', 'b', 'c','d','e'])
    
          a       b    c          d       e
    0  S.No    Name  Age       City  Salary
    1     1     Tom   28    Toronto   20000
    2     2     Lee   32   HongKong    3000
    3     3  Steven   43   Bay Area    8300
    4     4     Ram   38  Hyderabad    3900
    

    观察可以看到,标题名称附加了自定义名称,但文件中的标题还没有被消除。 现在,使用header参数来删除它。

    如果标题不是第一行,则将行号传递给标题。这将跳过前面的行。

    df=pd.read_csv("temp.csv",names=['a','b','c','d','e'],header=0)
    
       a       b   c          d      e
    0  1     Tom  28    Toronto  20000
    1  2     Lee  32   HongKong   3000
    2  3  Steven  43   Bay Area   8300
    3  4     Ram  38  Hyderabad   3900
    

    skiprows

    skiprows跳过指定的行数。

    df=pd.read_csv("temp.csv", skiprows=2)
    
       2     Lee  32   HongKong  3000
    0  3  Steven  43   Bay Area  8300
    1  4     Ram  38  Hyderabad  3900
    

    Pandas稀疏数据

    当任何匹配特定值的数据(NaN/缺失值,尽管可以选择任何值)被省略时,稀疏对象被“压缩”。 一个特殊的SparseIndex对象跟踪数据被“稀疏”的地方。 这将在一个例子中更有意义。 所有的标准Pandas数据结构都应用了to_sparse方法

    ts = pd.Series(np.random.randn(10))
    ts[2:-2] = np.nan
    sts = ts.to_sparse()
    
    0   -0.391926
    1   -1.774880
    2         NaN 
    3         NaN
    4         NaN
    5         NaN
    6         NaN
    7         NaN
    8    0.642988
    9   -0.373698
    dtype: float64
    BlockIndex
    Block locations: array([0, 8])
    Block lengths: array([2, 2])
    

    为了内存效率的原因,所以需要稀疏对象的存在。

    现在假设有一个大的NA DataFrame并执行下面的代码 -

    df = pd.DataFrame(np.random.randn(10000, 4))
    df.ix[:9998] = np.nan
    sdf = df.to_sparse()
    print (sdf.density)
    

    执行上面示例代码,得到以下结果 -

    0.0001
    Shell
    

    通过调用to_dense可以将任何稀疏对象转换回标准密集形式 -

    import pandas as pd
    import numpy as np
    ts = pd.Series(np.random.randn(10))
    ts[2:-2] = np.nan
    sts = ts.to_sparse()
    print (sts.to_dense())
    Python
    

    执行上面示例代码,得到以下结果 -

    0   -0.275846
    1    1.172722
    2         NaN
    3         NaN
    4         NaN
    5         NaN
    6         NaN
    7         NaN
    8   -0.612009
    9   -1.413996
    dtype: float64
    Shell
    

    稀疏Dtypes

    稀疏数据应该具有与其密集表示相同的dtype。 目前,支持float64int64booldtypes。 取决于原始的dtypefill_value默认值的更改 -

    • float64np.nan
    • int640
    • boolFalse

    执行下面的代码来理解相同的内容 -

    import pandas as pd
    import numpy as np
    
    s = pd.Series([1, np.nan, np.nan])
    print (s)
    print ("=============================")
    s.to_sparse()
    print (s)
    Python
    

    执行上面示例代码,得到以下结果 -

    0    1.0
    1    NaN
    2    NaN
    dtype: float64
    =============================
    0    1.0
    1    NaN
    2    NaN
    dtype: float64
    

    Pandas注意事项&窍门

    警告和疑难意味着一个看不见的问题。在使用Pandas过程中,需要特别注意的地方。

    与Pandas一起使用If/Truth语句

    当尝试将某些东西转换成布尔值时,Pandas遵循了一个错误的惯例。 这种情况发生在使用布尔运算的。 目前还不清楚结果是什么。 如果它是真的,因为它不是zerolength? 错误,因为有错误的值? 目前还不清楚,Pandas提出了一个ValueError

    import pandas as pd
    
    if pd.Series([False, True, False]):
        print ('I am True')
    
    ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
    

    if条件,它不清楚如何处理它。错误提示是否使用None或任何这些。

    import pandas as pd
    if pd.Series([False, True, False]).any():  # 任何True
        print("I am any")
    

    要在布尔上下文中评估单元素Pandas对象,请使用方法.bool()

    import pandas as pd
    print (pd.Series([True]).bool())  # 只能有一个值,结果:True
    

    按位布尔值

    按位布尔运算符(如==!=)将返回一个布尔系列,这几乎总是需要的。

    import pandas as pd
    
    s = pd.Series(range(5))
    print (s==4)
    

    执行上面示例代码,得到以下结果 -

    0    False
    1    False
    2    False
    3    False
    4     True
    dtype: bool
    

    isin操作符

    这将返回一个布尔序列,显示系列中的每个元素是否完全包含在传递的值序列中。

    import pandas as pd
    
    s = pd.Series(list('abc'))
    s = s.isin(['a', 'c', 'e'])
    print (s)
    
    0     True
    1    False
    2     True
    dtype: bool
    

    重构索引与ix陷阱

    许多用户会发现自己使用ix索引功能作为从Pandas对象中选择数据的简洁方法

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three',
    'four'],index=list('abcdef'))
    
    print (df)
    print ("=============================================")
    print (df.ix[['b', 'c', 'e']])
    

    执行上面示例代码,得到以下结果 -

            one       two     three      four
    a -1.174632  0.951047 -0.177007  1.036567
    b -0.806324 -0.562209  1.081449 -1.047623
    c  0.107607  0.778843 -0.063531 -1.073552
    d -0.277602 -0.962720  1.381249  0.868656
    e  0.576266  0.986949  0.433569  0.539558
    f -0.708917 -0.583124 -0.686753 -2.338110
    =============================================
            one       two     three      four
    b -0.806324 -0.562209  1.081449 -1.047623
    c  0.107607  0.778843 -0.063531 -1.073552
    e  0.576266  0.986949  0.433569  0.539558
    

    这当然在这种情况下完全等同于使用reindex方法

    import pandas as pd
    import numpy as np
    df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three',
    'four'],index=list('abcdef'))
    print (df)
    print("=============================================")
    print (df.reindex(['b', 'c', 'e']))
    

    执行上面示例代码,得到以下结果 -

            one       two     three      four
    a -1.754084 -1.423820 -0.152234 -1.475104
    b  1.508714 -0.216916 -0.184434 -2.117229
    c -0.409298 -0.224142  0.308175 -0.681308
    d  0.938517 -1.626353 -0.180770 -0.470252
    e  0.718043 -0.730215 -0.716810  0.546039
    f  2.313001  0.371286  0.359952  2.126530
    =============================================
            one       two     three      four
    b  1.508714 -0.216916 -0.184434 -2.117229
    c -0.409298 -0.224142  0.308175 -0.681308
    e  0.718043 -0.730215 -0.716810  0.546039
    

    有人可能会得出这样的结论,ixreindex是基于这个100%的等价物。 除了整数索引的情况,它是true。例如,上述操作可选地表示为 -

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randn(6, 4), columns=['one', 'two', 'three',
    'four'],index=list('abcdef'))
    
    print (df)
    print("=====================================")
    print (df.ix[[1, 2, 4]])
    print("=====================================")
    print (df.reindex([1, 2, 4]))
    
            one       two     three      four
    a  1.017408  0.594357 -0.760587  1.001547
    b -1.480067  1.524270  0.455070  1.886959
    c -0.136238 -0.165867 -0.589767 -1.078473
    d  0.670576  1.600312  0.219578 -1.121352
    e -0.224181  0.958156  0.013055 -0.013652
    f  1.576155 -0.185003 -0.527204 -0.336275
    =====================================
            one       two     three      four
    b -1.480067  1.524270  0.455070  1.886959
    c -0.136238 -0.165867 -0.589767 -1.078473
    e -0.224181  0.958156  0.013055 -0.013652
    =====================================
       one  two  three  four
    1  NaN  NaN    NaN   NaN
    2  NaN  NaN    NaN   NaN
    4  NaN  NaN    NaN   NaN
    Shell
    

    重要的是要记住,reindex只是严格的标签索引。这可能会导致一些潜在的令人惊讶的结果,例如索引包含整数和字符串的病态情况。

    Pandas与SQL比较

    由于许多潜在的Pandas用户对SQL有一定的了解,因此本文章旨在提供一些如何使用Pandas执行各种SQL操作的示例。

    import pandas as pd
    url = 'tips.csv'
    tips=pd.read_csv(url)
    print (tips.head())
    

    文件:tips.csv -

    total_bill,tip,sex,smoker,day,time,size
    0,16.99,1.01,Female,No,Sun,Dinner,2
    1,10.34,1.66,Male,No,Sun,Dinner,3
    2,21.01,3.50,Male,No,Sun,Dinner,3
    3,23.68,3.31,Male,No,Sun,Dinner,2
    4,24.59,3.61,Female,No,Sun,Dinner,4
    

    执行上面示例代码,得到以下结果 -

       total_bill   tip     sex smoker  day    time  size
    0       16.99  1.01  Female     No  Sun  Dinner     2
    1       10.34  1.66    Male     No  Sun  Dinner     3
    2       21.01  3.50    Male     No  Sun  Dinner     3
    3       23.68  3.31    Male     No  Sun  Dinner     2
    4       24.59  3.61  Female     No  Sun  Dinner     4
    

    选择(Select)

    在SQL中,选择是使用逗号分隔的列列表(或选择所有列)来完成的,例如 -

    SELECT total_bill, tip, smoker, time
    FROM tips
    LIMIT 5;
    SQL
    

    Pandas中,列的选择是通过传递列名到DataFrame -

    tips[['total_bill', 'tip', 'smoker', 'time']].head(5)
    Python
    

    下面来看看完整的程序 -

    import pandas as pd
    
    url = 'tips.csv'
    
    tips=pd.read_csv(url)
    rs = tips[['total_bill', 'tip', 'smoker', 'time']].head(5)
    print(rs)
    

    执行上面示例代码,得到以下结果 -

       total_bill   tip smoker    time
    0       16.99  1.01     No  Dinner
    1       10.34  1.66     No  Dinner
    2       21.01  3.50     No  Dinner
    3       23.68  3.31     No  Dinner
    4       24.59  3.61     No  Dinner
    

    调用没有列名称列表的DataFrame将显示所有列(类似于SQL的*)。

    WHERE条件

    SELECT * FROM tips WHERE time = 'Dinner' LIMIT 5;
    SQL
    

    数据帧可以通过多种方式进行过滤; 最直观的是使用布尔索引。

    tips[tips['time'] == 'Dinner'].head(5)
    Python
    

    下面来看看完整的程序 -

    import pandas as pd
    
    url = 'tips.csv'
    
    tips=pd.read_csv(url)
    rs = tips[tips['time'] == 'Dinner'].head(5)
    print(rs)
    

    执行上面示例代码,得到以下结果 -

       total_bill   tip     sex smoker  day    time  size
    0       16.99  1.01  Female     No  Sun  Dinner     2
    1       10.34  1.66    Male     No  Sun  Dinner     3
    2       21.01  3.50    Male     No  Sun  Dinner     3
    3       23.68  3.31    Male     No  Sun  Dinner     2
    4       24.59  3.61  Female     No  Sun  Dinner     4
    

    上述语句将一系列True/False对象传递给DataFrame,并将所有行返回True

    通过GroupBy分组

    此操作将获取整个数据集中每个组的记录数。 例如,一个查询提取性别的数量(即,按性别分组) -

    SELECT sex, count(*)
    FROM tips
    GROUP BY sex;
    SQL
    

    Pandas中的等值语句将是 -

    tips.groupby('sex').size()
    

    下面来看看完整的程序 -

    import pandas as pd
    
    url = 'tips.csv'
    
    tips=pd.read_csv(url)
    rs = tips.groupby('sex').size()
    print(rs)
    

    执行上面示例代码,得到以下结果 -

    sex
    Female    2
    Male      3
    dtype: int64
    

    前N行

    SQL(MySQL数据库)使用LIMIT返回前n行 -

    SELECT * FROM tips
    LIMIT 5 ;
    

    Pandas中的等值语句将是 -

    tips.head(5)
    

    下面来看看完整的程序 -

    import pandas as pd
    
    url = 'tips.csv'
    
    tips=pd.read_csv(url)
    rs = tips[['smoker', 'day', 'time']].head(5)
    print(rs)
    

    执行上面示例代码,得到以下结果 -

      smoker  day    time
    0     No  Sun  Dinner
    1     No  Sun  Dinner
    2     No  Sun  Dinner
    3     No  Sun  Dinner
    4     No  Sun  Dinner
    

    这些是比较的几个基本操作,在前几章的Pandas库中学到的。

  • 相关阅读:
    两个排序数组的第k小——Java实现
    单向链表反转——递归与非递归实现
    白话HMM系列3——维特比算法求解隐藏序列
    白话Shell命令1——top查看Linux进程
    白话HMM系列2——Baum Welch算法的进阶
    Hadoop原理深度剖析系列1——Hadoop的基本知识
    白话HMM系列1——从一个缩略语还原的例子说起
    软件工程第二次作业
    Hello World!
    查看帐号授权信息
  • 原文地址:https://www.cnblogs.com/pythonwl/p/14516067.html
Copyright © 2011-2022 走看看