利用Python進行數據分析——數據規整化:清理、轉換、合並、重塑(七)(1)


數據分析和建模方面的大量編程工作都是用在數據准備上的:載入、清理、轉換以及重塑。有時候,存放在文件或數據庫中的數據並不能滿足你的數據處理應用的要求。很多人都選擇使用通用編程語言(如Python、Perl、R或Java)或UNIX文本處理工具(如sed或awk)對數據格式進行專門處理。幸運的是,pandas和Python標准庫提供了一組高級的、靈活的、高效的核心函數和算法,它們使你可以輕松地將數據規整化為正確的形式。

1、合並數據集

pandas對象中的數據能夠通過一些內置的方式進行合並:

  • pandas.merge可依據一個或多個鍵將不同DataFrame中的行連接起來。SQL或其它關系型數據庫的用戶對此應該會比較熟悉,由於它實現的就是數據庫的連接操作。
  • pandas.concat能夠沿着一條軸將多個對象堆疊到一起。
  • 實例方法combine_first能夠將反復數據編接在一起,用一個對象中的值填充還有一個對象中的缺失值。


2、數據庫風格的DataFrame合並

數據集的合並(merge)或連接(join)運算是通過一個或多個鍵將行鏈接起來的。這些運算是關系型數據庫的核心。pandas的merge函數是對數據應用這些算法的主要切入點。

In [4]: import pandas as pd

In [5]: import numpy as np

In [6]: df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
   ...:                     'data1': range(7)})

In [7]: df2 = pd.DataFrame({'key': ['a', 'b', 'd'],
   ...:                     'data2': range(3)})

In [8]: df1
Out[8]: 
   data1 key
0      0   b
1      1   b
2      2   a
3      3   c
4      4   a
5      5   a
6      6   b

[7 rows x 2 columns]

In [9]: df2
Out[9]: 
   data2 key
0      0   a
1      1   b
2      2   d

[3 rows x 2 columns]
這是一種多對一的合並。df1中的數據有多個被標記為a和b的行,而df2中key列的每一個值則僅相應一行。對這些對象調用merge就可以得到:

In [10]: pd.merge(df1, df2)
Out[10]: 
   data1 key  data2
0      0   b      1
1      1   b      1
2      6   b      1
3      2   a      0
4      4   a      0
5      5   a      0

[6 rows x 3 columns]
注意,我並沒有指明要用哪個列進行連接。假設沒有指定,merge就會將重疊列的列名當做鍵。只是,最好顯示指定一下:

In [11]: pd.merge(df1, df2, on='key')
Out[11]: 
   data1 key  data2
0      0   b      1
1      1   b      1
2      6   b      1
3      2   a      0
4      4   a      0
5      5   a      0

[6 rows x 3 columns]
假設兩個對象的列名不同,也能夠分別進行指定:

In [12]: df3 = pd.DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
   ....:                     'data1': range(7)})

In [13]: df4 = pd.DataFrame({'rkey': ['a', 'b', 'd'],
   ....:                     'data2': range(3)})

In [14]: pd.merge(df)
df1  df2  df3  df4  

In [14]: pd.merge(df3, df4, left_on='lkey', right_on='rkey')
Out[14]: 
   data1 lkey  data2 rkey
0      0    b      1    b
1      1    b      1    b
2      6    b      1    b
3      2    a      0    a
4      4    a      0    a
5      5    a      0    a

[6 rows x 4 columns]
可能你已經主要到了,結果里面c和d以及與之相關的數據消失了。默認情況下,merge做的是“inner”連接;結果中的鍵是交集。其它方式還有“left”、“right”以及“outer”。外連接求取的是鍵的交集,組合了左連接和右連接的效果:

In [16]: pd.merge(df1, df2, how='outer')
Out[16]: 
   data1 key  data2
0      0   b      1
1      1   b      1
2      6   b      1
3      2   a      0
4      4   a      0
5      5   a      0
6      3   c    NaN
7    NaN   d      2

[8 rows x 3 columns]
多對多的合並操作很easy,無需額外的工作。例如以下所看到的:

In [17]: df1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
   ....:                     'data1': range(6)})

In [18]: df2 = pd.DataFrame({'key': ['a', 'b', 'a', 'b', 'd'],
   ....:                     'data2': range(5)})

In [19]: df1
Out[19]: 
   data1 key
0      0   b
1      1   b
2      2   a
3      3   c
4      4   a
5      5   b

[6 rows x 2 columns]

In [20]: df2
Out[20]: 
   data2 key
0      0   a
1      1   b
2      2   a
3      3   b
4      4   d

[5 rows x 2 columns]

In [21]: pd.merge(df1, df2, on='key', how='left')
Out[21]: 
    data1 key  data2
0       0   b      1
1       0   b      3
2       1   b      1
3       1   b      3
4       5   b      1
5       5   b      3
6       2   a      0
7       2   a      2
8       4   a      0
9       4   a      2
10      3   c    NaN

[11 rows x 3 columns]
多對多連接產生的是行的笛卡爾積。因為左邊的DataFrame有3個“b”行,右邊的有2個,所以終於結果中就有6個“b”行。連接方式僅僅影響出如今結果中的鍵:

In [23]: pd.merge(df1, df2, on='key', how='inner')
Out[23]: 
   data1 key  data2
0      0   b      1
1      0   b      3
2      1   b      1
3      1   b      3
4      5   b      1
5      5   b      3
6      2   a      0
7      2   a      2
8      4   a      0
9      4   a      2

[10 rows x 3 columns]
要依據多個鍵進行合並,傳入一個由列名組成的列表就可以:

In [24]: left = pd.DataFrame({'key1': ['foo', 'foo', 'bar'],
   ....:                      'key2': ['one', 'two', 'one'],
   ....:                      'lval': [1, 2, 3]})

In [25]: right = pd.DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'],
   ....:                       'key2': ['one', 'one', 'one', 'two'],
   ....:                       'rval': [4, 5, 6, 7]})

In [26]: pd.merge(left, right, on=['key1', 'key2'], how='outer')
Out[26]: 
  key1 key2  lval  rval
0  foo  one     1     4
1  foo  one     1     5
2  foo  two     2   NaN
3  bar  one     3     6
4  bar  two   NaN     7

[5 rows x 4 columns]
結果中會出現哪些鍵組合取決於所選的合並方式,你能夠這樣來理解:多個鍵形成一系列元組,並將其當做單個連接鍵(當然,實際上並非這么回事)。

警告:

在進行列-列連接時,DataFrame對象中的索引會被丟棄。

對於合並運算須要須要考慮的最后一個問題是對反復列名的處理。盡管你能夠手工處理列名重疊的問題,但merge有一個更有用的suffixes選項,用於指定附加到左右兩個DataFrame對象的重疊列名上的字符串:

In [27]: pd.merge(left, right, on='key1')
Out[27]: 
  key1 key2_x  lval key2_y  rval
0  foo    one     1    one     4
1  foo    one     1    one     5
2  foo    two     2    one     4
3  foo    two     2    one     5
4  bar    one     3    one     6
5  bar    one     3    two     7

[6 rows x 5 columns]

In [28]: pd.merge(left, right, on='key1', suffixes=('_left', '_right'))
Out[28]: 
  key1 key2_left  lval key2_right  rval
0  foo       one     1        one     4
1  foo       one     1        one     5
2  foo       two     2        one     4
3  foo       two     2        one     5
4  bar       one     3        one     6
5  bar       one     3        two     7

[6 rows x 5 columns]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM