Pandas 数据处理

Pandas

數據準備工作

​ 黨您獲取到數據時,往往數據是冗雜且紛亂的。因此,我們需要對數據進行一系列的準備工作,如:加載,組裝,刪除等…………。(當然,一般官方庫的數據均是處理完備可以直接進行使用的

數據合并

數據合并則使用函數 pd.merge(DataFrame_1, DataFrame_2),在使用時需注意,需保持兩個 DataFrame 對象的長度一致。

整個合并過程類似於 “交” 操作,即保留 columns的值相同的項,儅 columns 中有多項 Index 相同時,則(很大可能)會篩除掉更多的數據。具體請看下方實例。

frame1 = pd.DataFrame({"id":["A", "B", "C", "D"],
                       "values":[100, 200, 300, 500]})
print(frame1)

frame2 = pd.DataFrame({"id":["A", "B","E", "C"],
                        "values":[500, 200, 300, 500]})
print()
print(pd.merge(frame1, frame2))
-------------------------------------
  id  values
0  A     100
1  B     200
2  C     300
3  D     500

  id  values
0  B     200
frame1 = pd.DataFrame({"id":["A", "B", "C", "D"],
                       "values":[100, 200, 300, 500]})
print(frame1)

frame2 = pd.DataFrame({"id":["A", "B","E", "C"],
                       "objects":["a", "c", "e", "f"]})
print()
print(pd.merge(frame1, frame2))
-----------------------------------------
  id  values
0  A     100
1  B     200
2  C     300
3  D     500

  id  values objects
0  A     100       a
1  B     200       c
2  C     300       f

可以看到,儅進行合并時,若2個 DataFrame 對象的 Columns 相同,則會篩除掉更多的數據(因要保證數據更高的相同性),若有額外的 Columns_value 出現,則會附加在後邊(如 objects 所示)。

另外,也可以設置參數 on = ““,來指定函數進行合并所選的列。

frame1 = pd.DataFrame({"id":["A", "B", "C", "D"],
                       "values":[100, 200, 300, 500],
                       "objects":["da", "da", "qwe", "qwe"]},
                        )
frame2 = pd.DataFrame({"id":["A", "B","E", "C"],
                       "objects":["a", "c", "e", "f"]})
print(pd.merge(frame1, frame2))
print()
print(pd.merge(frame1, frame2, on="id"))
------------------------------------------------
Empty DataFrame
Columns: [id, values, objects]
Index: []

  id  values objects_x objects_y
0  A     100        da         a
1  B     200        da         c
2  C     300       qwe         f

現在您清楚了吧。(不是

那麽,黨兩個 DataFrame 對象沒有相同的 columns 值該怎麽辦呢?若在此時用上述的方法進行合并,那麽最後結果均是空列表。如下所示:

frame1 = pd.DataFrame({"id":["A", "B", "C", "D"],
                       "values":[100, 200, 300, 500],
                       "objects":["da", "da", "qwe", "qwe"]},
                        )
frame2 = pd.DataFrame({"sid":["A", "B","E", "C"],
                       "objects":["a", "c", "e", "f"]})
print(pd.merge(frame1, frame2))

-------------------------------------
Empty DataFrame
Columns: [id, values, objects, sid]
Index: []

這時,我們就可以使用 DataFrame() 中的參數 left_on 和 right_on,來指定合并時需要進行比較的 Columns 的值。當然,既可以使用 key 值進行指定,也可以使用索引值(left_index)。

print(pd.merge(frame1, frame2,left_on="id", right_on="sid"))
-----------------------------
 id  values objects_x sid objects_y
0  A     100        da   A         a
1  B     200        da   B         c
2  C     300       qwe   C         f

在連接時,也可以對 how = “” 參數進行調整以改變鏈接的方式。how = “left” 進行左連接;how = “right” 進行右鏈接, how = “outer”進行外連接。此處的三種鏈接方式與數據庫中的定義相同,便不再進行闡釋。

若要根據索引進行合并,可使用 pd.merge(left_index =True, right_index = True) 或 使用 DataFrame.join() 來進行合并。(即橫向匹配

frame1 = pd.DataFrame({"id":["A", "B", "C", "D"],
                       "values":[100, 200, 300, 500],
                       "objects":["da", "da", "qwe", "qwe"]},
                        )
frame2 = pd.DataFrame({"sid":["A", "B","E", "C", "Q"],
                       "objects":["a", "c", "e", "f", "haha"]})
print(pd.merge(frame1, frame2))
# print()
# print(pd.merge(frame1, frame2,left_on="id", right_on="sid"))

print(pd.merge(frame1, frame2, left_index=True, right_index=True))
--------------------------------------
Empty DataFrame
Columns: [id, values, objects, sid]
Index: []

  id  values objects_x sid objects_y
0  A     100        da   A         a
1  B     200        da   B         c
2  C     300       qwe   E         e
3  D     500       qwe   C         f

然而若使用 frame1.join(frame2),則會報錯。因爲此時 frame1 和 frame 2的 columns 具有重複的值。

frame1 = pd.DataFrame({"id":["A", "B", "C", "D"],
                       "values":[100, 200, 300, 500],
                       "objects":["da", "da", "qwe", "qwe"]},
                        )
frame2 = pd.DataFrame({"sid":["A", "B","E", "C", "G"],
                       "objects1":["a", "c", "e", "f", "haha"]})
print()
print(frame1.join(frame2))
--------------------------------------
  id  values objects sid objects1
0  A     100      da   A        a
1  B     200      da   B        c
2  C     300     qwe   E        e
3  D     500     qwe   C        f

數據拼接

需要用到的函數:

​ pd.concat(),包括參數:[序列], keys,axis。

在進行數據準備時,數據(或稱爲數組更容易理解)的拼接也是常做的工作。

不難想象,拼接既有竪向拼接,也有橫向拼接。

簡單的拼接(注意這個方括號哦~)

frame1 = pd.DataFrame(np.arange(9).reshape(3, 3),
                      columns=["A", "B", "C"],
                      index=["a", "b", "c"])
frame2 = pd.DataFrame(np.arange(9).reshape(3, 3),
                      columns=["D", "E", "F"],
                      index=["d", "e", "f"])

print()
print(pd.concat([frame1, frame2]))
-----------------------------------------
     A    B    C    D    E    F
a  0.0  1.0  2.0  NaN  NaN  NaN
b  3.0  4.0  5.0  NaN  NaN  NaN
c  6.0  7.0  8.0  NaN  NaN  NaN
d  NaN  NaN  NaN  0.0  1.0  2.0
e  NaN  NaN  NaN  3.0  4.0  5.0

通過 key 參數,來辨別拼接而成的各個部分


frame1 = pd.DataFrame(np.arange(9).reshape(3, 3),
                      columns=["A", "B", "C"],
                      index=["a", "b", "c"])
frame2 = pd.DataFrame(np.arange(9).reshape(3, 3),
                      columns=["D", "E", "F"],
                      index=["d", "e", "f"])
print(pd.concat([frame1, frame2], keys = ["First", "Second"]))
-----------------------------------------
            A    B    C    D    E    F
First  a  0.0  1.0  2.0  NaN  NaN  NaN
       b  3.0  4.0  5.0  NaN  NaN  NaN
       c  6.0  7.0  8.0  NaN  NaN  NaN
Second d  NaN  NaN  NaN  0.0  1.0  2.0
       e  NaN  NaN  NaN  3.0  4.0  5.0
       f  NaN  NaN  NaN  6.0  7.0  8.0

根據 axis 參數,來調整拼接的方向,其默認, axis = 0即為橫向拼接;黨 axis = 1時,則竪著并列。

frame1 = pd.DataFrame(np.arange(9).reshape(3, 3),
                      columns=["A", "B", "C"],
                      index=["a", "b", "c"])
frame2 = pd.DataFrame(np.arange(9).reshape(3, 3),
                      columns=["D", "E", "F"],
                      index=["d", "e", "f"])
print(pd.concat([frame1, frame2], keys = ["First", "Second"], axis=1))
----------------------------------
  First           Second          
      A    B    C      D    E    F
a   0.0  1.0  2.0    NaN  NaN  NaN
b   3.0  4.0  5.0    NaN  NaN  NaN
c   6.0  7.0  8.0    NaN  NaN  NaN
d   NaN  NaN  NaN    0.0  1.0  2.0
e   NaN  NaN  NaN    3.0  4.0  5.0
f   NaN  NaN  NaN    6.0  7.0  8.0

數據組合

書上寫到,儅兩個數據集的索引完全或部分相同時,可以通過“組合” 來組合數據。(不是很能理解)不過還是來講講函數的具體使用方法。

使用DataFrame.combine_first( ) 函數即可達到進行組合的目的。

frame1 = pd.DataFrame(np.arange(9).reshape(3, 3),
                      columns=["A", "B", "C"],
                      index=["a", "b", "c"])

frame2 = pd.DataFrame(np.arange(16).reshape(4, 4),
                      columns=["C","D", "E", "F"],
                      index=["c","d", "e", "f"])

print(frame1.combine_first(frame2))
----------------------------------------
     A    B     C     D     E     F
a  0.0  1.0   2.0   NaN   NaN   NaN
b  3.0  4.0   5.0   NaN   NaN   NaN
c  6.0  7.0   8.0   1.0   2.0   3.0
d  NaN  NaN   4.0   5.0   6.0   7.0
e  NaN  NaN   8.0   9.0  10.0  11.0
f  NaN  NaN  12.0  13.0  14.0  15.0

最後達到的效果,類似於拼接 + 填充(即自己沒有的可以從另外一個 DataFrame 中拿出來)。

軸向旋轉

黨你想把列 轉化為 行時,可以使用 DataFrame.stack()函數。演示如下:

import pandas as pd
import numpy as np

frame1 = pd.DataFrame(np.arange(9).reshape(3, 3),
                      columns=["A", "B", "C"],
                      index=["a", "b", "c"])

print(frame1)
print()
print(frame1.stack())
------------------------------
   A  B  C
a  0  1  2
b  3  4  5
c  6  7  8

a  A    0
   B    1
   C    2
b  A    3
   B    4
   C    5
c  A    6
   B    7
   C    8
dtype: int32

使用函數 DataFrame.unstack()可以把行轉換為列(即 stack() 的逆過程)。


frame1 = pd.DataFrame(np.arange(9).reshape(3, 3),
                      columns=["A", "B", "C"],
                      index=["a", "b", "c"])

print(frame1)
print()
print(frame1.unstack())
------------------------------
   A  B  C
a  0  1  2
b  3  4  5
c  6  7  8

A  a    0
   b    3
   c    6
B  a    1
   b    4
   c    7
C  a    2
   b    5
   c    8
dtype: int32

運用 DataFrame.pivot(index=, columns =, values = ) 既可以提取 原對象columns屬性下可能多次出現的值,然後以達到將 “瘦”的數據變成”胖”數據的目的。(可能解釋的不是很清楚,具體請看下方的演示。

data = {'date': ['2018-08-01', '2018-08-02', '2018-08-03', '2018-08-01', '2018-08-03', '2018-08-03',
                 '2018-08-01', '2018-08-02'],
        'variable': ['A','A','A','B','B','C','C','C'],
        'value': [3.0 ,4.0 ,6.0 ,2.0 ,8.0 ,4.0 ,10.0 ,1.0 ]}

frame2 = pd.DataFrame(data, columns=["date", "variable", "value"])
print(frame2)
print()
print(frame2.pivot(index="date", columns="variable",values="value"))
--------------------------------------------------
         date variable  value
0  2018-08-01        A    3.0
1  2018-08-02        A    4.0
2  2018-08-03        A    6.0
3  2018-08-01        B    2.0
4  2018-08-03        B    8.0
5  2018-08-03        C    4.0
6  2018-08-01        C   10.0
7  2018-08-02        C    1.0

variable      A    B     C
date                      
2018-08-01  3.0  2.0  10.0
2018-08-02  4.0  NaN   1.0
2018-08-03  6.0  8.0   4.0

Process finished with exit code 0

刪除

刪除可分爲刪除行或刪除列,同第四章所講的一樣,可以通過 del 和 DataFrame.drop() 來達到刪除的目的。接下來將會在下文一一闡述。

使用 del 時要注意,只能對 columns 進行刪除,而不能對 index 進行刪除。

df = pd.DataFrame(np.arange(9).reshape(3, 3),
                  columns=["A", "B", "C"],
                  index=["a", "b", "c"])
print(df)
del df["A"]
print()
print(df)
-----------------------------
   A  B  C
a  0  1  2
b  3  4  5
c  6  7  8

   B  C
a  1  2
b  4  5
c  7  8

通過 DataFrame.drop() 即可刪除你想刪除的行(即索引:index)

df = pd.DataFrame(np.arange(9).reshape(3, 3),
                  columns=["A", "B", "C"],
                  index=["a", "b", "c"])
print(df)
df = df.drop("a")
print()
print(df)
-----------------------------
   A  B  C
a  0  1  2
b  3  4  5
c  6  7  8

   A  B  C
b  3  4  5
c  6  7  8                 

數據轉換

刪除重複的元素

當你的數據中出現重複的數據后,你可能會考慮將其刪除掉,也可能會不。(不是

通過 DataFrame.duplicated() 可以來檢測重複出現的數據。

ps: 對於這種進行判斷的函數,大部分(不確定)可用於X[X.xxxx()] 條件判斷中用於生成對應的單個元素。

df = pd.DataFrame({"color":["red", "red", "blue", "green", "yellow"],
                   "values":[1, 1, 3, 5, 5]})

print(df)
print()
print(df.duplicated())
print()
print(df[df.duplicated()])
--------------------------------
    color  values
0     red       1
1     red       1
2    blue       3
3   green       5
4  yellow       5

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

  color  values
1   red       1

映射關係

對於映射關係的理解,可以聯想 PYTHON 中的字典。在字典中, key 和 value 一一對應,這就是一種映射關係。

替換元素

通過映射,可以實現將元素替換的效果。使用 DataFrame.replace() 即可達到。其中的參數為 {old: new}這種。

df = pd.DataFrame({"objects":["pen", "pencil", "bigpen"],
                   "values":[100, 300, 500]})
print(df)
df = df.replace({"pen":"bigbigpen","bigpen":"littlepen"})
print(df)
-------------------------
  objects  values
0     pen     100
1  pencil     300
2  bigpen     500

     objects  values
0  bigbigpen     100
1     pencil     300
2  littlepen     500

添加元素

通過映射關係,我們還可以往數據裏邊添加一列。需要使用到 DataFrame.map()。

df = pd.DataFrame({"objects":["pen", "pencil", "bigpen"],
                   "values":[100, 300, 500]})

price = {100: 123, 300: 456, 500: 789}
df["price"] = df["values"].map(price)
print(df)
-----------------------------------------
  objects  values  price
0     pen     100    123
1  pencil     300    456
2  bigpen     500    789

通過前一列的數據和映射關係,即可將 price 成功添加到 DataFrame 中去。

軸的重命名

當你對你的軸的名稱不滿意時,你也可以對其進行更改。大致方式與👆文處添加元素一致。只不過此處調用的并非 .map() 而是 .rename()。

df = pd.DataFrame(np.arange(25).reshape(5, 5),
                  columns=["A", "B", "C", "D", "E",],
                  index=["a", "b", "c", "d", "e"])
print(df)

reindex_ = {"A": "AAAAA",
           "B": "BBBBB",
           "C": "CCCCC",
           "D": "DDDDD",
           "E": "EEEEE"}

df = df.rename(columns=reindex_)
print()
print(df)
-----------------------------
    A   B   C   D   E
a   0   1   2   3   4
b   5   6   7   8   9
c  10  11  12  13  14
d  15  16  17  18  19
e  20  21  22  23  24

   AAAAA  BBBBB  CCCCC  DDDDD  EEEEE
a      0      1      2      3      4
b      5      6      7      8      9
c     10     11     12     13     14
d     15     16     17     18     19
e     20     21     22     23     24

此處需注意,若直接傳入字典參數,則其默認修改的是 index ,若要對行(表頭)進行修改,需要顯性的寫出 columns = xxxx。

離散化和面元劃分

由於我們和算法對數據的不同需求,我們可能會需要離散化的數據,也可能會需要連續的數據,因此對數據進行離散化也是一個非常重要的過程。

簡單來説,將連續的數據拆分開的過程就叫離散化,所拆分的一組一組的就是“面元。”(離散化和面元劃分其實就是一類東西啦

進行劃分前,可以先通過列表定義面元,然後再通過 pd.cut()函數對數據進行劃分。

data = np.random.randint(0, 100, 50)
bins = [0, 25, 50, 75, 100]
print(data)
print()
print(pd.cut(data, bins))
----------------------------------------
[70 10 99 92  9 48 68 66 38 12  5 62 89 56 59 88  4 93 87  7  3 22 78 75
 30 62 46 60 51 64 29 52  8 40 90  7  8 44 49 47 29 49 28 79  7 43 12 33
 29 30]

[(50, 75], (0, 25], (75, 100], (75, 100], (0, 25], ..., (25, 50], (0, 25], (25, 50], (25, 50], (25, 50]]
Length: 50
Categories (4, interval[int64]): [(0, 25] < (25, 50] < (50, 75] < (75, 100]]

若在調用cut() 函數時不指定面元的各界限,而是僅僅傳入一個整數作爲參數, cut()會按照指定的數字將元素按照範圍劃分為相應的幾部分。

注意:這裏是按照數字將元素劃爲等分的區域,并不代表著每個區域中的元素個數都是相同的。

data = np.random.randint(0, 100, 50)
bins = [0, 25, 50, 75, 100]
print(pd.cut(data, 5))
---------------------------------
[(-0.097, 19.4], (19.4, 38.8], (77.6, 97.0], (58.2, 77.6], (58.2, 77.6], ..., (-0.097, 19.4], (38.8, 58.2], (-0.097, 19.4], (-0.097, 19.4], (77.6, 97.0]]
Length: 50
Categories (5, interval[float64]): [(-0.097, 19.4] < (19.4, 38.8] < (38.8, 58.2] < (58.2, 77.6] <
                                    (77.6, 97.0]]

次數計算

通過 pd.value_counts() 函數可以計算各個面元出現的次數。

ata = np.random.randint(0, 100, 50)
bins = [0, 25, 50, 75, 100]
cut_result = pd.cut(data,bins)
print(pd.value_counts(cut_result))
-----------------------------------------
(75, 100]    18
(50, 75]     12
(25, 50]     11
(0, 25]       9
dtype: int64

通過 cut_result(這是個變量名) .codes 可以得出各個元素屬於哪個面元。(其中面元從0開始至len(arr) - 1,也就是面元劃分的各個下標)

data = np.random.randint(0, 100, 50)
bins = [0, 25, 50, 75, 100]
print(cut_result.codes)
-------------------------------------
[3 2 0 1 1 2 1 0 1 1 2 3 1 0 0 3 3 0 2 3 3 3 1 0 1 1 2 1 0 2 1 0 0 2 1 1 3
 0 3 1 2 0 3 2 3 0 2 0 0 2]

名稱指定

通過一個X元的列表(其中X 應與面元的個數保持一致,才能達到名稱指定(1對1)的作用),來指定面元的名稱。其中需主要的是,在調用 cut 函數時需顯性寫出參數 labels =

data = np.random.randint(0, 100, 50)
bins = [0, 25, 50, 75, 100]
bin_names = ["unlikely", "less likely", "likely", "high likely"]
print(pd.cut(data, bins, labels=bin_names))
-------------------------------------------------
['unlikely', 'likely', 'less likely', 'less likely', 'likely', ..., 'high likely', 'less likely', 'unlikely', 'high likely', 'high likely']
Length: 50
Categories (4, object): ['unlikely' < 'less likely' < 'likely' < 'high likely']

排序

改變行排列或列排列

通過 DataFrame.take()即可以實現對行排位或列排位的改變。不難想到,此處同樣可以通過對參數 axis 的控制來實現對行或是對列的操作。

df = pd.DataFrame(np.arange(25).reshape(5, 5))
new_order = np.random.permutation(5)
print(new_order)
print()
print(df.take(new_order))
-------------------------------------------
[2 3 1 4 0]

    0   1   2   3   4
2  10  11  12  13  14
3  15  16  17  18  19
1   5   6   7   8   9
4  20  21  22  23  24
0   0   1   2   3   4

此處,補充一下random.permutation()。這個函數用於創建一個包含0 至 x (不包括x)有 x 個整數的數組。這 X 個數均會被包括,但其出現的順序則是隨機的。

字符串處理

可能會用到的函數:

  • .split()
  • .join()
  • .index()
  • .find()
  • .replace()

正則表達式

(沒想到還是逃不過正則)

首先講一下什麽是正則表達式。

正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本編輯器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。

(不過老師跳過了,那我們也略。

數據聚合

所謂數據聚合,即是將數組中的多個數據進行會聚,最後生成一個單一的數值。

Groupby

在pandas中,數據的聚合通過 Groupby() 函數,生成一個 Groupby對象,具體的信息均可通過 Groupby 獲取。

frame = pd.DataFrame({"color": ["red", "blue", "green"],
                      "object": ["pen", "ball", "pencil"],
                      "value":[5, 10, 15],
                      "value2":[20, 25,50]},)

print(frame["value"])
group = frame["value"].groupby(frame["color"])
print(group.groups)
print()
print(group.mean())
-----------------------------------
0     5
1    10
2    15
Name: value, dtype: int64
{'blue': [1], 'green': [2], 'red': [0]}

color
blue     10
green    15
red       5
Name: value, dtype: int64

顯而易見,這個 DataFrame 首先應該是由數值和字符串一起構成的。

在使用 groupby 函數時,首先應指定你想要聚類在哪個方向上(或者稱爲哪個屬性上),將其傳遞在參數中;然後用被聚類的屬性來調用這個 groupby() 函數,就如上述代碼中的:frame[“value”].groupby(frame[“color”]),可理解為 A is grouped by (B)。

若想查看 group 對象,需使用屬性 groups 而非直接 print();另外,.mean(),.max() 這些方法肯定也是會具有的。

等級分組

當然,可以根據一列來進行聚類,就可以根據多累來進行聚類。只需在傳入參數時多寫幾個進去就可以了。(簡單吧

另外,被聚類的數據同時也可以不止一個屬性哦~

ps:所以這種方法爲什麽叫等級分組呢?

frame = pd.DataFrame({"color": ["red", "blue", "green"],
                      "object": ["pen", "ball", "pencil"],
                      "value":[5, 10, 15],
                      "value2":[20, 25,50]},)

group = frame[["value", "value2"]].groupby(frame["color"])
print(group.groups)
print()
print(group.mean())
print("==========================")
print(frame.groupby(frame["object"]).mean())
--------------------------------
{'blue': [1], 'green': [2], 'red': [0]}

       value  value2
color               
blue      10      25
green     15      50
red        5      20
==========================
        value  value2
object               
ball       10      25
pen         5      20
pencil     15      50

由此可以看出,當單獨使用 frame.groupby() 而不指定被聚類屬性時,其會自動選擇 DataFrame 對象中的 為數值的 屬性,而非由字符串組成的屬性。

組迭代

.groupby() 函數返回的是一個可迭代對象,其組成類似於 dict 中的 (key, value) 鍵值對。

import pandas as pd
import numpy as np

frame = pd.DataFrame({"color": ["red", "blue", "green"],
                      "object": ["pen", "ball", "pencil"],
                      "value":[5, 10, 15],
                      "value2":[20, 25,50]},)

for name, group in frame.groupby(frame["color"]):
    print(name)
    print(group)
----------------------------------
blue
  color object  value  value2
1  blue   ball     10      25
green
   color  object  value  value2
2  green  pencil     15      50
red
  color object  value  value2
0   red    pen      5      20

鏈式轉換

鏈式轉換看起來可能會很酷,但實際上并不推薦大家使用(鄙人私自認爲)。

故不再進行介紹。(不是

分組函數

通過調用函數 quantile() 計算分位數即可達到分組的效果。有些同學可能就疑惑了,分位數是個什麽東西?下面簡單介紹一下分位數。

分位數是一個數值,它代表了在整個序列(或列表)中,前百分之多少的數會小於該數。用人話來説,就是將數組進行排序,然後在百分比多少的位置對數據進行劃分。

frame = pd.DataFrame({"color": ["red", "blue", "green"],
                      "object": ["pen", "ball", "pencil"],
                      "value":[5, 10, 15],
                      "value2":[20, 25,50]},)

print(frame.quantile(0.6))
---------------------------------
value     11.0
value2    30.0
Name: 0.6, dtype: float64

一般來説,分組函數可以配合 groupby() 一起使用。將數組進整體行分組后再進行内部劃分。

自定義聚類函數

通過 .agg() 可以實現自定義聚類函數的功能哦。


frame = pd.DataFrame(np.arange(9).reshape(3, 3),
                        columns = ["red", "blue", "green"],
                      index =  ["pen", "ball", "pencil"])

group = frame.groupby(frame.index)

print(group.mean())
print()
print(group.agg(mydef))
print()
print(frame.agg(mydef))
----------------------------------------------
       red  blue  green
ball      3     4      5
pen       0     1      2
pencil    6     7      8

        red  blue  green
ball      0     0      0
pen       0     0      0
pencil    0     0      0

red      6
blue     6
green    6
dtype: int64

高級數據聚合

(很難不懷疑爲什麽教材把這個内容放在章節末)

需要使用到的函數:

  • .transform()
  • .apply()

示例如下:

add_prefix() 用於修改index,groupby()用於在 color(本例中)進行聚類。

.transform(func) 其中func 是用於轉換的函數,既可以傳入自定義函數,也可以傳入庫中所包括的函數。


frame = pd.DataFrame({"color": ["white", "red", "green", "red", "green"],
                      "price1":[2, 5, 7, 9, 10],
                      "price2":[11, 33, 55, 77, 99]})

print(frame.groupby(frame["color"]).transform(np.sum).add_prefix("tot_"))
---------------------------------
   tot_price1  tot_price2
0           2          11
1          14         110
2          17         154
3          14         110
4          17         154

apply() 函數適用於更加通用的 Groupby() 操作。

frame = pd.DataFrame({"color": ["white", "black", "white", "black", "white"],
                      "status":["up", "up", "down", "down", "down"],
                      "value1":[12, 13, 15, 16, 17],
                      "value2": [21, 25, 26, 27, 29]})

print(frame.groupby(["color", "status"]).apply(lambda x:x.max()))
-----------------------------------------------
			  color status  value1  value2
color status                              
black down    black   down      16      27
      up      black     up      13      25
white down    white   down      17      29
      up      white     up      12      21

注:如果沒看懂,其實也沒有關係。