Pandas基礎(chǔ)之系統(tǒng)入門(mén)

第1章 入門(mén)知識(shí)


  1. 簡(jiǎn)述:用于操作行列數(shù)據(jù),方便地實(shí)現(xiàn)各種形式的數(shù)據(jù)分析;
  2. Pandas最初主要應(yīng)用于金融數(shù)據(jù)分析工作,其為時(shí)間序列分析提供了很好的支持;
  3. Pandas的名稱(chēng)來(lái)自于面板數(shù)據(jù)(panel data)和Python數(shù)據(jù)分析(data analysis)
  4. panel data是經(jīng)濟(jì)學(xué)中關(guān)于多維數(shù)據(jù)集的一個(gè)術(shù)語(yǔ),在Pandas中也提供了panel的數(shù)據(jù)類(lèi)型(新版本已停用);
  5. 適用的數(shù)據(jù)類(lèi)型
  • 具有異構(gòu)類(lèi)型列的表格數(shù)據(jù),如SQL表格或Excel數(shù)據(jù);
  • 有序和無(wú)序(不一定是固定頻率)時(shí)間序列數(shù)據(jù);
  • 具有行列標(biāo)簽的任意矩陣數(shù)據(jù)(均勻類(lèi)型或不同類(lèi)型);
  • 任何其他形式的觀(guān)測(cè)/統(tǒng)計(jì)數(shù)據(jù)集。


第2章 數(shù)據(jù)結(jié)構(gòu)


  1. 作為一個(gè)python庫(kù),python中的數(shù)據(jù)類(lèi)型在pandas中依然適用
  2. 核心數(shù)據(jù)結(jié)構(gòu)
  • Series:一維、帶有索引、同類(lèi)型元素的數(shù)組,與Numpy中的一維array類(lèi)似;
  • DateFrame:二維、帶有索引、大小可變、可以不同類(lèi)型元素的表格數(shù)據(jù),可以看作是Series的容器,即一個(gè)DateFrame可以包含若干個(gè)Series

第3章 創(chuàng)建對(duì)象


  1. Series:標(biāo)量值列表,默認(rèn)索引為整數(shù);
    pd.Series([1, 3, 5, np.nan, 6, 8])
    0    1.0
    1    3.0
    2    5.0
    3    NaN
    4    6.0
    5    8.0
    dtype: float64
    
  2. Dataframe:帶有日期時(shí)間的索引、Numpy數(shù)組;
    dates = pd.date_range('2018-07-10', periods=6)
    
    dates
    -- > DatetimeIndex(['2018-07-10', '2018-07-11', '2018-07-12', '2018-07-13','2018-07-14', '2018-07-15'],
                        dtype='datetime64[ns]', freq='D')
    
    df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
    
    print(df) 
                   A            B           C           D
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913
    2018-07-15  0.863050    0.442406    0.871964    1.107883
    
  3. Dataframe:可以轉(zhuǎn)換為類(lèi)似Series系列的dict對(duì)象;
    df2 = pd.DataFrame({
                    'A':1.,
                    'B':pd.Timestamp('20180710'),
                    'C':pd.Series(1, index=list(range(4)), dtype='float32'),
                    'D':np.array([2]*4, dtype='int32'),
                    'E':np.array([1, 2, 3, 4], dtype='int64'),
                    'F':pd.Categorical(['test', 'learn', 'test', 'learn']),
                    'G':'xz'
                    })  
    
    print(df2)
        A   B           C   D   E   F       G
    0   1.0 2018-07-10  1.0 2   1   test    xz
    1   1.0 2018-07-10  1.0 2   2   learn   xz
    2   1.0 2018-07-10  1.0 2   3   test    xz
    3   1.0 2018-07-10  1.0 2   4   learn   xz
    
  4. DataFrame的不同列,具有不同的dtypes
    print(df2.dtypes)
    
    A           float64
    B    datetime64[ns]
    C           float32
    D             int32
    E             int64
    F          category
    G            object
    dtype: object
    


第4章 查看數(shù)據(jù)


  1. head(x)查看頂行數(shù)據(jù)、tail(x)查看底行數(shù)據(jù),x表示查看的行數(shù),默認(rèn)為5;
    df2.head(2)   #查看頂部2行數(shù)據(jù)
        A   B           C   D   E   F       G
    0   1   2018-07-10  1   2   1   test    xz
    1   1   2018-07-10  1   2   2   learn   xz
    
    df2.tail(3)  # 查看底部3行數(shù)據(jù)
        A   B           C   D   E   F       G
    1   1   2018-07-10  1   2   2   learn   xz
    2   1   2018-07-10  1   2   3   test    xz
    3   1   2018-07-10  1   2   4   learn   xz
    
  2. 查看索引、列名稱(chēng)、基礎(chǔ)Numpy數(shù)據(jù);
    df2.index
    -- > Int64Index([0, 1, 2, 3], dtype='int64')
    
    df2.columns
    -- > Index(['A', 'B', 'C', 'D', 'E', 'F', 'G'], dtype='object')
    
    df2.values
    array([[1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 1, 'test', 'xz'],
           [1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 2, 'learn', 'xz'],
           [1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 3, 'test', 'xz'],
           [1.0, Timestamp('2018-07-10 00:00:00'), 1.0, 2, 4, 'learn', 'xz']], dtype=object)
    
  3. 描述性統(tǒng)計(jì);
    df.describe()
                A           B           C           D
    count   6.000000    6.000000    6.000000    6.000000
    mean    -0.203846   -0.520712   0.252811    0.056574
    std     1.824972    0.629551    1.047736    0.535639
    min     -2.441260   -1.616401   -0.849088   -0.795480
    25%     -1.805976   -0.669989   -0.564042   -0.165330
    50%     0.214104    -0.472665   0.257587    0.142493
    75%     1.160094    -0.065817   0.595098    0.291087
    max     1.793887    0.103427    1.981094    0.777256
    
  4. 轉(zhuǎn)置數(shù)據(jù)
    df2.T
        0   1   2   3
    A   1   1   1   1
    B   2018-07-10 00:00:00 2018-07-10 00:00:00 2018-07-10 00:00:00 2018-07-10 00:00:00
    C   1   1   1   1
    D   2   2   2   2
    E   1   2   3   4
    F   test    learn   test    learn
    G   xz  xz  xz  xz
    


第5章 選取數(shù)據(jù)


  1. 獲取一列,即Series
    df.A  # 等同于 df['A']
    2018-07-10   -0.177312
    2018-07-11   -2.441260
    2018-07-12   -2.348864
    2018-07-13    0.605520
    2018-07-14    1.344952
    2018-07-15    1.793887
    Freq: D, Name: A, dtype: float64    
    
  2. 行切片:索引或值
    df[:3]  # 索引切片
                    A           B           C           D
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    
    df['2018-07-11':'2018-07-14']  # 值切片
                    A            B          C           D
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913
    
  3. 函數(shù):loc[]、iloc[]
  • loc[]:根據(jù)行或列的索引值,獲取數(shù)據(jù),含下限,可僅取行或列;
  • iloc[]:根據(jù)行或列的索引位置,獲取數(shù)據(jù),不含下限,可僅取行或列;
  • 僅取一行
    df.loc['2018-07-11']    等同于    df.iloc[1]
    
    A   -1.508561
    B   -0.173393
    C    0.815395
    D   -1.242897
    Name: 2018-07-11 00:00:00, dtype: float64
    
  • 僅取一列
    df.loc[:,'C']     等同于    df.iloc[:,2] 
    
    2018-07-10    0.809279
    2018-07-11    0.815395
    2018-07-12   -0.915480
    2018-07-13   -1.636825
    2018-07-14   -1.208112
    2018-07-15    0.871964
    Freq: D, Name: C, dtype: float64
    
  • 行列連續(xù)截取
    df.loc['2018-07-12':'2018-07-14',['B', 'C', 'D']]    等同于    df.iloc[2:5, 1:4]
    
                    B             C         D
    2018-07-12  -0.462607   -0.915480   2.595037
    2018-07-13  -0.216765   -1.636825   -0.671588
    2018-07-14  0.270277    -1.208112   1.982913
    
    說(shuō)明:loc[]在選取行索引值時(shí),可以類(lèi)似切片的形式,但是在選取列索引時(shí),只能一個(gè)一個(gè)列舉,不能像類(lèi)似切片的形式用冒號(hào)連接取連續(xù)的中間值。
    
  • 行列不連續(xù)截取
    df.iloc[[0,5],[0,3]]   # iloc[]行列均可以不連續(xù)截取數(shù)據(jù)
                    A           D
    2018-07-10  -0.710755   -0.718210
    2018-07-15  0.863050    1.107883
        
    
    df.loc['2017-07-10':'2018-07-15', ['A', 'D']]  # loc[]行索引  不  可以不連續(xù)截取
                    A           D
    2018-07-10  -0.710755   -0.718210
    2018-07-11  -1.508561   -1.242897
    2018-07-12  -2.157823   2.595037
    2018-07-13  0.826433    -0.671588
    2018-07-14  -0.438337   1.982913
    2018-07-15  0.863050    1.107883
    
  • 獲取單個(gè)值
    df.loc['2018-07-14', 'C']    等同于    df.iloc[4,2]
    -1.2081117496772031
    
  • 補(bǔ)充loc[]、iloc[]方法也可以對(duì)DataFrame進(jìn)行賦值等操作。
  1. 布爾判斷:多列值判斷時(shí),&表示and的關(guān)系,|表示or的關(guān)系
    df[df.C < 0.5]    #單個(gè)列值判斷
                    A           B           C           D
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913
    
    df[(df.A < 0) & (df.D > 0)]  
                    A           B           C          D
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913
    
    df[df > 0]  #DataFrame值判斷
                  A  B      C        D
    2018-07-10  NaN NaN 0.809279    NaN
    2018-07-11  NaN NaN 0.815395    NaN
    2018-07-12  NaN NaN NaN 2.595037
    2018-07-13  0.826433    NaN NaN NaN
    2018-07-14  NaN 0.270277    NaN 1.982913
    2018-07-15  0.863050    0.442406    0.871964    1.107883
    
  2. 過(guò)濾函數(shù):isin()
    df2 = df.copy()
    df2['E'] = ['one', 'two', 'three', 'four', 'five', 'six']
    print(df2)
                    A         B         C         D        E
    2018-07-10 -0.710755 -0.757183  0.809279 -0.718210    one
    2018-07-11 -1.508561 -0.173393  0.815395 -1.242897    two
    2018-07-12 -2.157823 -0.462607 -0.915480  2.595037  three
    2018-07-13  0.826433 -0.216765 -1.636825 -0.671588   four
    2018-07-14 -0.438337  0.270277 -1.208112  1.982913   five
    2018-07-15  0.863050  0.442406  0.871964  1.107883    six
    
    df2[df2.E.isin(['two', 'five'])]
                    A           B           C           D       E
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897   two
    2018-07-14  -0.438337   0.270277    -1.208112   1.982913    five
    
  3. 模糊匹配:contains()
    df2[df2.E.str.contains('o')]  # 選取E列中含有關(guān)鍵字“o”的數(shù)據(jù)
                    A           B           C           D       E
    2018-07-10  -1.738617   -1.013051   -1.938631   -1.049786   one
    2018-07-11  -0.719089   -1.042707   -0.616299   0.460417    two
    2018-07-13  -0.446243   -2.036736   1.469567    0.256282    four
    
  4. 獲取數(shù)據(jù)的方法,同樣可以對(duì)DataFrame進(jìn)行重新賦值。

第6章 缺失值


  1. Pandas使用np.nan來(lái)表示缺失的數(shù)據(jù),默認(rèn)不包含在計(jì)算中;
  2. 準(zhǔn)備數(shù)據(jù)
    df3 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])  # 增加索引,默認(rèn)數(shù)據(jù)均為空
    df3.iloc[0:2, 4] = 1  # 賦值
    print(df3)
                   A         B         C         D       E
    2018-07-10 -0.177312 -0.456757 -0.849088  0.107067   1
    2018-07-11 -2.441260 -0.730461  1.981094  0.177919   1
    2018-07-12 -2.348864  0.103427  0.607445 -0.795480 NaN
    2018-07-13  0.605520 -0.488574  0.558058  0.328810 NaN
    
  3. 刪除任何缺少數(shù)據(jù)的行
    df3.dropna(how='any')  # axis=1時(shí)刪除列數(shù)據(jù)、how=all時(shí)所有值均為空時(shí)才刪除
                    A           B           C           D       E
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210   1.0
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897   1.0
    
  4. 替換缺失值
    df3.fillna(1000)   #將空值替換為1000
                    A           B           C           D       E
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210   1.0
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897   1.0
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037    1000.0
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588   1000.0
    
  5. 判斷缺失值
    pd.isna(df3) # 不同的pandas版本,可以用isnull()
                  A       B       C       D      E
    2018-07-10  False   False   False   False   False
    2018-07-11  False   False   False   False   False
    2018-07-12  False   False   False   False   True
    2018-07-13  False   False   False   False   True
    


第7章 排序


  1. 按索引排序
  • 語(yǔ)法:sort_index(axis=0/1, ascengding=True/False)
  • axis缺失或?yàn)?時(shí),按行索引排序,為1時(shí)按列索引(columns)排序;
  • ascengding缺失或?yàn)門(mén)rue時(shí),表示升序,為False時(shí)表示降序;
  • 示例
    df3.sort_index(axis=1, ascending=False)  #列排序,降序
                 E      D          C            B           A
    2018-07-10  1.0 -0.718210   0.809279    -0.757183   -0.710755
    2018-07-11  1.0 -1.242897   0.815395    -0.173393   -1.508561
    2018-07-12  NaN 2.595037    -0.915480   -0.462607   -2.157823
    2018-07-13  NaN -0.671588   -1.636825   -0.216765   0.826433
    
  1. 按值排序
  • 語(yǔ)法:sort_values(by='colums_name', ascengding=True/False)
  • 示例
    df3.sort_values(by=['D', 'C'], ascending=False)
                    A           B           C           D       E
    2018-07-12  -2.157823   -0.462607   -0.915480   2.595037    NaN
    2018-07-13  0.826433    -0.216765   -1.636825   -0.671588   NaN
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210   1.0
    2018-07-11  -1.508561   -0.173393   0.815395    -1.242897   1.0
    
  1. 自定義排序
  • 步驟
    • 第一步:將需要自定義排序的字段,設(shè)置為“category”數(shù)據(jù)類(lèi)型
    • 第二步:對(duì)字段進(jìn)行自定義排序
    • 第三步:對(duì)DataFrame進(jìn)行排序
  • 準(zhǔn)備數(shù)據(jù)
    df_sort = pd.DataFrame({
        "word":['a', 'b', 'c'],
        "number":[1, 2, 3]})
    
    print(df_sort)
    word    number
    0   a   1
    1   b   2
    2   c   3
    
    # 需要排列的順序
    sort_column = ['c', 'b', 'a'] 
    
  • 示例
    df_sort.word = df.word.astype('category')  #把排序字段設(shè)置為"category"類(lèi)型
    df_sort.word.cat.reorder_categories(sort_column, inplace=True)   # 字段按自定義排序
    df_sort.sort_values('word',inplace=True)   # DataFrame按自定義排序
    
    print(df_sort)
      word  number
    2   c   3
    1   b   2
    0   a   1
    


第8章 常用操作


  1. 統(tǒng)計(jì):mean(x)count(x)min(x)max(x)std(x)等,x為0時(shí)是行操作、x為1時(shí)是列操作。統(tǒng)計(jì)時(shí)上述函數(shù)會(huì)忽略缺失值。
    df3.mean()    #統(tǒng)計(jì)每列的均值
    A   -0.887676
    B   -0.402487
    C   -0.231908
    D   -0.009415
    E    1.000000
    dtype: float64
    
    df3.max(1)  #統(tǒng)計(jì)每行的最大值
    2018-07-10    1.000000
    2018-07-11    1.000000
    2018-07-12    2.595037
    2018-07-13    0.826433
    Freq: D, dtype: float64
    
  2. 函數(shù):apply()
    df3.apply(np.cumsum)  #統(tǒng)計(jì)每列的累加和
                    A           B           C           D       E
    2018-07-10  -0.710755   -0.757183   0.809279    -0.718210   1.0
    2018-07-11  -2.219316   -0.930576   1.624674    -1.961108   2.0
    2018-07-12  -4.377138   -1.393183   0.709194    0.633930    NaN
    2018-07-13  -3.550705   -1.609948   -0.927632   -0.037658   NaN
    
    df3.apply(lambda x: x.max() - x.min(), axis=1)  #統(tǒng)計(jì)每行最大值與最小值之差
    2018-07-10    1.757183
    2018-07-11    2.508561
    2018-07-12    4.752860
    2018-07-13    2.463258
    Freq: D, dtype: float64
    
  3. 求和、不同值計(jì)數(shù)
    np.sum(df3.C)    # 對(duì)C列求和
    -0.927631569447292
    
    df3.E.value_counts()  # 對(duì)E列不同值計(jì)數(shù),自動(dòng)忽略空值
    1.0    2
    Name: E, dtype: int64
    
  4. 字符串方法str
    df4 = pd.DataFrame({"A":['foo', 'bar', 'bar', 'xz'],
                        "B":['one', 'two', 'one', 'two'],
                        "C":['Small', 'Small', 'Large', 'Large'],
                        "D":[1, 2, 3, 4]})
    print(df4)
        A    B    C     D
    0   foo one Small   1
    1   bar two Small   2
    2   bar one Large   3
    3   xz  two Large   4
    
    df4.C.str.lower()  # 字符串轉(zhuǎn)換為 小寫(xiě)
    0    small
    1    small
    2    large
    3    large
    Name: C, dtype: object
    
    df4[df4.A.str.endswith('r')]  #字符串結(jié)尾字符篩選
        A   B    C      D
    1   bar two Small   2
    2   bar one Large   3
    


第9章 合并


  1. 關(guān)聯(lián)merge()
  • 用法:通過(guò) 橫向拼接,類(lèi)似sql中的join,通過(guò)一個(gè)或多個(gè)鍵將不同的DataFrame關(guān)聯(lián)
  • 參數(shù)說(shuō)明
    • how : inner、outer、left、right 關(guān)聯(lián)方式
    • on : [key1, key2......] 同字段名關(guān)聯(lián)
    • left_on / right_on 、 left_key / right_key、left_index / right_index 不同字段名關(guān)聯(lián)
    • left_index / right_index = True時(shí),表示按索引進(jìn)行匹配
  • 多對(duì)多關(guān)聯(lián)
    left = pd.DataFrame({'key':['xz', 'xz'], 'value':[1, 2]})
    print(left)
       key  value
    0  xz      1
    1  xz      2
    right = pd.DataFrame({'key':['xz', 'xz'], 'value':[5, 6]})
    print(right)
    key  value
    0  xz      5
    1  xz      6
    
    join = pd.merge(left, right, on='key')   #多對(duì)多關(guān)聯(lián)
    print(join)
       key  value_x  value_y
    0  xz        1        5
    1  xz        1        6
    2  xz        2        5
    3  xz        2        6
    
  • 一對(duì)一關(guān)聯(lián)
    left = pd.DataFrame({'key':['xz', 'ab'], 'value':[1, 2]})
    print(left)
    key  value
    0  xz      1
    1  ab      2
    right = pd.DataFrame({'key':['xz', 'ab'], 'value':[5, 6]})
    print(right)
    key  value
    0  xz      5
    1  ab      6
    
    join = pd.merge(left, right, on='key')  # 一對(duì)一關(guān)聯(lián)
    print(join)
       key  value_x  value_y
    0  xz        1        5
    1  ab        2        6
    
  1. 追加append()
  • 用法:縱向追加數(shù)據(jù),橫向同時(shí)擴(kuò)充,不考慮columns和index,數(shù)據(jù)列不一樣時(shí),設(shè)置ignore_index = True
  • 示例
    df5 = pd.DataFrame(np.random.randint(10, 20, [2,4]),columns=list('ABCD'))
    print(df5) 
        A   B   C   D
    0  19  16  15  15
    1  16  15  16  10
    
    s = df5[1:] 
    print(s)
        A   B   C   D
    1  16  15  16  10
    
    df5.append(s, ignore_index=True)   # ignore_index:默認(rèn)為False, 若為T(mén)rue,表示不要使用索引標(biāo)簽
        A   B   C   D
    0   19  16  15  15
    1   16  15  16  10
    2   16  15  16  10
    
  1. 拼接concat()
  • 用法:?jiǎn)渭兊谋砥唇樱梢?code>橫向或縱向,可以一次性拼接多個(gè)表,結(jié)果不去重復(fù),需要指定軸進(jìn)行連接,drop_duplicates()可以去重復(fù)。
  • 參數(shù)說(shuō)明
    • objs :連接對(duì)象,如:Series、DataFrame、list
    • axis = 0 時(shí),與append()方法相同;axis = 1時(shí),與merge()方法相同
    • join :inner、outer(默認(rèn))
    • join_axes :設(shè)置需要保留的表索引
    • ignore_index :是否忽略原索引
    • keys :為原連接對(duì)象添加一個(gè)鍵,便于后期分組統(tǒng)計(jì)
  • 示例
    df6 = pd.DataFrame(np.random.randn(8, 4))
    print(df6)
           0         1         2         3
    0  1.259128  1.352209  0.934947  0.734223
    1 -0.567591 -1.114880 -1.540007  0.192176
    2  1.007433  0.774980  1.229243  1.413190
    3  1.029385  0.316052  0.363644  1.310764
    4 -0.414858  2.030369  1.910180 -0.785533
    5  0.684923 -0.064547 -1.475371 -0.842338
    6 -0.289478  2.119747  0.519206 -2.564895
    7  0.958962 -1.278468  0.099762  0.226029
    
    pd.concat([df6[:2], df6[3:5], df6[7:]], keys=['x', 'y', 'z'])
               0            1           2           3
    x   0   1.259128    1.352209    0.934947    0.734223
        1   -0.567591   -1.114880   -1.540007   0.192176
    y   3   1.029385    0.316052    0.363644    1.310764
        4   -0.414858   2.030369    1.910180    -0.785533
    z   7   0.958962    -1.278468   0.099762    0.226029
    
  1. 合并join()
  • 用法:默認(rèn)以index為拼接列,其參數(shù)與merge方法基本一致,默認(rèn) how = left ,可以合并相同或相似的索引,目前已較少使用。

第10章 分組


  1. 列分組--列運(yùn)算

    df7 = pd.DataFrame({'A': list('XYZXYZXYZX'), 
                       'B': [1, 2, 1, 3, 1, 2, 3, 3, 1, 2], 
                       'C': [12, 14, 11, 12, 13, 14, 16, 12, 10, 19]})
    print(df7)
        A   B   C
    0   X   1   12
    1   Y   2   14
    2   Z   1   11
    3   X   3   12
    4   Y   1   13
    5   Z   2   14
    6   X   3   16
    7   Y   3   12
    8   Z   1   10
    9   X   2   19
    
    df7.groupby('A').C.mean()  # 按A列分組,統(tǒng)計(jì)C列的均值
    A
    X    14.750000
    Y    13.000000
    Z    11.666667
    Name: C, dtype: float64
    
  2. 列分組--多種運(yùn)算

    df7.groupby('A').B.agg([np.mean,np.std])
           mean     std
    A       
    X   2.250000    0.957427
    Y   2.000000    1.000000
    Z   1.333333    0.577350
    
  3. 列分組--相同運(yùn)算

    df7.groupby('A')['B', 'C'].mean()
            B           C
    A       
    X   2.250000    14.750000
    Y   2.000000    13.000000
    Z   1.333333    11.666667
    
  4. 列分組--不同運(yùn)算

    df7.groupby('A')['B', 'C'].agg({'B': 'count', 'C': 'sum'})  
        B   C
    A       
    X   4   59
    Y   3   39
    Z   3   35
    說(shuō)明:在分組統(tǒng)計(jì)時(shí),一般的統(tǒng)計(jì)函數(shù)會(huì)自動(dòng)忽略空值,計(jì)數(shù)時(shí)使用`size()`函數(shù),會(huì)包含空值。
    
  5. 列分組--多個(gè)不同運(yùn)算

    df7.groupby('A').agg({'B':[np.mean, 'sum'], 'C':['count', np.std]}) 
           B            C
          mean    sum  count  std
    A               
    X   2.250000    9   4   3.403430
    Y   2.000000    6   3   1.000000
    Z   1.333333    4   3   2.081666
    
  6. 列分組--列運(yùn)算

    df7.groupby(['A', 'B']).C.sum()
    A  B
    X  1    12
       2    19
       3    28
    Y  1    13
       2    14
       3    12
    Z  1    21
       2    14
    
    說(shuō)明:多列分組后的各種運(yùn)算,和單列分組后一樣,不再舉例。
    
  7. 函數(shù)apply()+lambda()

    df7.groupby('A').apply(lambda x: (x['C'] - x['B']).mean())  # B列與C列之差的均值
         A
    X    12.500000
    Y    11.000000
    Z    10.333333
    
  8. 函數(shù)transform()

  • 聚合運(yùn)算時(shí),通常輸出的結(jié)果是一個(gè)以分組名為 index 的結(jié)果對(duì)象,若需要使用原數(shù)組的 index ,即把聚合結(jié)果關(guān)聯(lián)到原數(shù)組對(duì)象時(shí),使用該函數(shù)。
  • 示例
    # 普通的分組
    df7.groupby(['A', 'B']).C.count()
    A  B
    X  1    1
       2    1
       3    2
    Y  1    1
       2    1
       3    1
    Z  1    2
       2    1
    
    df7['count'] = df7.groupby(['A', 'B']).C.transform('count')
    print(df7)
        A   B   C  count
    0   X   1   12  1
    1   Y   2   14  1
    2   Z   1   11  2
    3   X   3   12  2
    4   Y   1   13  1
    5   Z   2   14  1
    6   X   3   16  2
    7   Y   3   12  1
    8   Z   1   10  2
    9   X   2   19  1
    
  1. 分段分組
  • 分段函數(shù)cut():將數(shù)據(jù)值分段,主要用于將連續(xù)變量轉(zhuǎn)換為分類(lèi)變量
  • 等距離分段:數(shù)據(jù)中的最小值和最大值,左右側(cè)各擴(kuò)展0.1%,做為分段邊界;
    df8 = pd.DataFrame({'Age': np.random.randint(20, 70, 15), 
                       'Sex': np.random.choice(['Male', 'Female'], 15), 
                       'num': np.random.randint(1, 20, 15)}) 
    print(df8)
        Age Sex   num
    0   22  Male    6
    1   49  Male    12
    2   52  Female  13
    3   29  Female  1
    4   46  Male    18
    5   64  Female  2
    6   42  Male    9
    7   33  Male    15
    8   25  Male    16
    9   38  Male    4
    10  32  Male    8
    11  28  Male    8
    12  31  Male    8
    13  62  Male    6
    14  40  Male    13
    
    pd.cut(df8['Age'], bins=3)  #等距離分割
    0     (21.958, 36.0]
    1       (36.0, 50.0]
    2       (50.0, 64.0]
    3     (21.958, 36.0]
    4       (36.0, 50.0]
    5       (50.0, 64.0]
    6       (36.0, 50.0]
    7     (21.958, 36.0]
    8     (21.958, 36.0]
    9       (36.0, 50.0]
    10    (21.958, 36.0]
    11    (21.958, 36.0]
    12    (21.958, 36.0]
    13      (50.0, 64.0]
    14      (36.0, 50.0]
    Name: Age, dtype: category
    Categories (3, interval[float64]): [(21.958, 36.0] < (36.0, 50.0] < (50.0, 64.0]]
    
    df8.groupby(pd.cut(df8['Age'], bins=3)).mean()  # 等距分組
                        Age     num
    Age     
    (21.958, 36.0]  28.571429   8.857143
    (36.0, 50.0]    43.000000   11.200000
    (50.0, 64.0]    59.333333   7.000000
    
  • 自定義范圍分段:范圍段可以不均勻
    pd.cut(df8['Age'], bins=[0,30,50,np.inf])  #自定義范圍進(jìn)行分割,可以不均勻
    0      (50.0, inf]
    1      (0.0, 30.0]
    2      (50.0, inf]
    3      (0.0, 30.0]
    4     (30.0, 50.0]
    5      (50.0, inf]
    6      (50.0, inf]
    7     (30.0, 50.0]
    8      (0.0, 30.0]
    9     (30.0, 50.0]
    10     (50.0, inf]
    11     (0.0, 30.0]
    12     (50.0, inf]
    13    (30.0, 50.0]
    14     (50.0, inf]
    Name: Age, dtype: category
    Categories (3, interval[float64]): [(0.0, 30.0] < (30.0, 50.0] < (50.0, inf]]
    
    # 自定義分段進(jìn)行分組統(tǒng)計(jì)
    df8.groupby(pd.cut(df8['Age'], bins=[0, 30, 50, np.inf])).mean()
                      Age         num
    Age     
    (0.0, 30.0]     23.250000   8.250000
    (30.0, 50.0]    37.000000   9.250000
    (50.0, inf]     59.428571   10.428571
    
  1. 統(tǒng)計(jì)頻率
  • 交叉表crosstab():一種特殊的pivot_table(),主要于計(jì)算分段分組頻率;
  • 對(duì)指定列分段后,再進(jìn)行分組,經(jīng)常需要計(jì)算分組頻率;
  • 對(duì)字段Age分段后,計(jì)算Sex的分組頻率,即按 Age 的分組范圍和性別 Sex 進(jìn)行制作交叉表。
    pd.crosstab(pd.cut(df8.Age, bins=[0, 30, 50, np.inf]), df8.Sex)
    
    Sex         Female  Male
    Age     
    (0.0, 30.0]     1   3
    (30.0, 50.0]    0   8
    (50.0, inf]     2   1
    


第11章 透視表


  1. pivot_table()
  • 參數(shù)說(shuō)明
param instroduction
data DataFrame
value 待聚合的列名稱(chēng),默認(rèn)聚合所有數(shù)據(jù)列
index 用于分組的列名或其他分組鍵,出現(xiàn)在結(jié)果透視表的
columns 用于分組的列名或其他分組鍵,出現(xiàn)在結(jié)果透視表的
aggfunc 聚合函數(shù)或函數(shù)列表,默認(rèn)為mean。可以使任何對(duì)groupby有效的函數(shù)
fill_value 用于替換結(jié)果表中的缺失值
dropna boolean,默認(rèn)為T(mén)rue
margins 是否添加匯總的行列
margins_name 默認(rèn)為all,margins=True時(shí)設(shè)置匯總行列的名稱(chēng)
  • 準(zhǔn)備數(shù)據(jù)
    df9 = pd.DataFrame({
        "A": ["foo", "foo", "foo", "foo", "foo","bar", "bar", "bar", "bar"],
        "B": ["one", "one", "one", "two", "two","one", "one", "two", "two"],
        "C": ["small", "large", "large", "small","small", "large", "small", "small","large"],
        "D": [1, 2, 3, 4, 3, 4, 5, 6, 7]})
    print(df9)
        A    B      C   D
    0  foo  one  small  1
    1  foo  one  large  2
    2  foo  one  large  3
    3  foo  two  small  4
    4  foo  two  small  3
    5  bar  one  large  4
    6  bar  one  small  5
    7  bar  two  small  6
    8  bar  two  large  7
    
  • 默認(rèn)聚合方法
    pd.pivot_table(df9, index=['A', 'B'], columns='C', values='D')   #默認(rèn)聚合函數(shù)為均值
    
    C     large small
    A   B       
    bar one 4.0 5.0
        two 7.0 6.0
    foo one 2.5 1.0
        two NaN 3.5
    
  • 設(shè)置聚合方法
    # 設(shè)置單個(gè)聚合方法
    pd.pivot_table(df9, index=['A', 'B'], columns='C', values='D', aggfunc=np.sum, fill_value=0)  #求和、空值設(shè)置為0
    
    C     large small
    A   B       
    bar one 4   5
        two 7   6
    foo one 5   1
        two 0   7
    
    # 設(shè)置多個(gè)聚合方法
    df9['E'] = [8, 9, 10, 11, 12, 13, 14, 15, 16]   
    pd.pivot_table(df13, values=['D', 'E'], index=['A', 'C'],
                                 aggfunc={'D': np.mean,
                                          'E': [min, max, np.median]})
                D          E
                mean      max   median  min
    A   C               
    bar large   5.500000    16  14.5    13
        small   5.500000    15  14.5    14
    foo large   2.500000    10  9.5 9
        small   2.666667    12  11.0    8
    
  1. pivot()
  • 透視后,不進(jìn)行統(tǒng)計(jì)處理,主要用來(lái)處理非數(shù)字?jǐn)?shù)據(jù),進(jìn)行行列轉(zhuǎn)換;
  • index只能是一個(gè)指定的列,indexcolumns對(duì)應(yīng)的數(shù)據(jù)元組,不能有重復(fù),否則會(huì)報(bào)錯(cuò)。
  • 準(zhǔn)備數(shù)據(jù)
    df10 = pd.DataFrame({
        "A": ["foo",  "bar", "bar", "xz"],
        "B": ["one",  "two", "one",  "two"],
        "C": ["small", "large", "large", "small"],
        "D": [1, 2, 3, 4]})
    
    print(df10) 
        A    B      C  D
    0  foo  one  small  1
    1  bar  two  large  2
    2  bar  one  large  3
    3   xz  two  small  4
    
  • 示例
    df10.pivot(index='A', columns='B', values='D')
    B   one two
    A       
    bar 3.0 2.0
    foo 1.0 NaN
    xz  NaN 4.0
    


第12章 其它

  1. 操作文件
  • 以csv格式文件為例,讀取read_csv()、寫(xiě)入to_csv()
  • 常見(jiàn)格式:excel、txt、sql、html、json等
  1. 常用操作
  • 查看列的數(shù)據(jù)類(lèi)型:df.dtypes
  • 查看數(shù)據(jù)詳情:df.info()
  • 刪除A列 : df.drop(A, axis = 1)
  • 更改列名 : df = df.rename(columns = {'old_name': 'new_name'})
  • 替換值 : df.replace(to_replace, values)
  • 設(shè)置列數(shù)據(jù)類(lèi)型:df.A = df.A.values.astype(‘float64’)
  • 日期字符串轉(zhuǎn)date:pd.to_datetime(df.date).dt.date
  • 日期字符串轉(zhuǎn)時(shí)間戳:pd.to_datetime(df.date).dt.to_pydatetime()
  1. 時(shí)間處理dt
  • 用途:作用于datetime64[ns]/timedelta64[ns]等日期型數(shù)據(jù),獲取datetimelike屬性的Accessor對(duì)象
  • 設(shè)置日期格式 : dt.strftime()
  • 獲取日期中的信息:dt.date / dt.year / dt.month / dt.time / dt.weekday / dt.dayofyear / dt.weekofyear
  • 設(shè)置日期運(yùn)算單位 : [datetime1 - datetime2].dt.days
  1. 合并列cat
  • 語(yǔ)法:df['A'].str.cat([df['B'], df['C']], sep='-')
  • 合并的2列的內(nèi)容必須是字符串,如果是數(shù)值型則會(huì)報(bào)錯(cuò),需要先轉(zhuǎn)換類(lèi)型;
  • 當(dāng)需要將某列的內(nèi)容都加上一個(gè)指定字符時(shí),可以先創(chuàng)建一個(gè)由該字符組成的臨時(shí)列,再合并。
  1. DataFrame四則運(yùn)算
  • add : 加法運(yùn)算,舉例:DataFrame1.add(DataFrame2, fill_value=0)
  • sub : 減法運(yùn)算,舉例:DataFrame1.sub(DataFrame2, fill_value=0)
  • mul : 乘法運(yùn)算,舉例:DataFrame1.mul(DataFrame2)
  • div : 除法運(yùn)算,舉例:DataFrame1.div(DataFrame2)
  • 說(shuō)明 : 上述參數(shù)DataFrame2可以是:Series、DataFrame、constant,Series類(lèi)型的數(shù)據(jù),也有類(lèi)似如上的四則運(yùn)算。
  1. 設(shè)置顯示選項(xiàng) : pandas.set_option(pat, value)
  • 保留小數(shù)點(diǎn)后的n位數(shù):("precision", n)
  • 展示n列:("max_columns", n)
  • 展示n行:("max_rows", n)
  • 絕對(duì)值小于n的顯示為0:("chop_threshold", n)
  • pd.options.mode.chained_assignment = None :關(guān)閉掉copywarning
  • pd.options.display.max_columns = 999 :設(shè)置顯示的列數(shù)
  1. 常見(jiàn)的小坑
  • DataFrame合并一個(gè)Series時(shí),會(huì)重新排列生成的列順序,默認(rèn)按字母順序。特別是,使用loc[]iloc[]選取的Series,建議,先to_frame().T轉(zhuǎn)成DataFrame后再合并
  • 列中類(lèi)似:date、datetime、time型的字符串?dāng)?shù)據(jù),需要轉(zhuǎn)為datetime64[ns]日期數(shù)據(jù),如df.date = pd.to_datetime(df.date),才能進(jìn)行選取:df[df.date == '2018-11-11']
  • 列中datetime64[ns]日期數(shù)據(jù),進(jìn)行大小判斷選取數(shù)據(jù)時(shí),與空值比較,結(jié)果為空;
  • 數(shù)據(jù)列中存在空數(shù)據(jù)NaN,使用astype()對(duì)其數(shù)據(jù)類(lèi)型進(jìn)行轉(zhuǎn)化時(shí),需要先將空數(shù)據(jù)NaN排除掉,否則函數(shù)不起作用。其參數(shù)errors只是對(duì)無(wú)法進(jìn)行轉(zhuǎn)換類(lèi)型的數(shù)據(jù)(非空)進(jìn)行處理;
  • 對(duì)df[df.condition] = value,即重新賦值時(shí),會(huì)報(bào)警,解決辦法:需要重新copy()一份,即df[df.condition].copy()后,再賦值。
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
  1. groupby分組后,需要統(tǒng)計(jì)的字段較多且有條件判斷時(shí),使用apply() + lambda + pd.Series()來(lái)快速實(shí)現(xiàn);
  2. 在pandas中,沒(méi)有isnotin函數(shù),可以通過(guò)取反的方式實(shí)現(xiàn),取反的方法就是在函數(shù)前面加個(gè)~。例如:~(df.A == 4) ,等效于 df.A != 4。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容