Python數(shù)據(jù)分析_Pandas02_數(shù)據(jù)框的合并和重整

主要內(nèi)容:
  • 數(shù)據(jù)拼接:join、merge弟翘、contact、append
  • 數(shù)據(jù)重整:reshape -- stuck、unstuck
  • 數(shù)據(jù)透視表:pivot tables

數(shù)據(jù)拼接

1. concat

參數(shù)介紹:

pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
          keys=None, levels=None, names=None, verify_integrity=False,
          copy=True)

axis:要粘在哪個軸上萎坷。默認0,粘貼行沐兰。
join:默認outer哆档,合集;inner住闯,交集瓜浸。
ignore_index:布爾型澳淑,默認False。如果為Ture的話插佛,會重新分配index從0...n-1杠巡。
keys:一個序列,默認None雇寇。建立等級索引氢拥,作為最外層的level。
levels:序列sequences構(gòu)成的list锨侯,默認None嫩海。

示例:

In [41]: df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
    ...:                     'B': ['B0', 'B1', 'B2', 'B3'],
    ...:                     'C': ['C0', 'C1', 'C2', 'C3'],
    ...:                     'D': ['D0', 'D1', 'D2', 'D3']},
    ...:                     index=[0, 1, 2, 3])

In [42]: df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
    ...:                     'B': ['B4', 'B5', 'B6', 'B7'],
    ...:                     'C': ['C4', 'C5', 'C6', 'C7'],
    ...:                     'D': ['D4', 'D5', 'D6', 'D7']},
    ...:                      index=[4, 5, 6, 7])
    ...:

In [43]: df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
    ...:                     'B': ['B8', 'B9', 'B10', 'B11'],
    ...:                     'C': ['C8', 'C9', 'C10', 'C11'],
    ...:                     'D': ['D8', 'D9', 'D10', 'D11']},
    ...:                     index=[8, 9, 10, 11])
    ...:

In [44]: frames = [df1, df2, df3]

In [45]: result = pd.concat(frames)

In [46]: result
Out[46]:
      A    B    C    D
0    A0   B0   C0   D0
1    A1   B1   C1   D1
2    A2   B2   C2   D2
3    A3   B3   C3   D3
4    A4   B4   C4   D4
5    A5   B5   C5   D5
6    A6   B6   C6   D6
7    A7   B7   C7   D7
8    A8   B8   C8   D8
9    A9   B9   C9   D9
10  A10  B10  C10  D10
11  A11  B11  C11  D11

In [47]:  result2 = pd.concat(frames, keys=['x', 'y', 'z'])

In [48]: result2
Out[48]:
        A    B    C    D
x 0    A0   B0   C0   D0
  1    A1   B1   C1   D1
  2    A2   B2   C2   D2
  3    A3   B3   C3   D3
y 4    A4   B4   C4   D4
  5    A5   B5   C5   D5
  6    A6   B6   C6   D6
  7    A7   B7   C7   D7
z 8    A8   B8   C8   D8
  9    A9   B9   C9   D9
  10  A10  B10  C10  D10
  11  A11  B11  C11  D11

In [51]: result2.index    # result2的shape是(12,4),多重索引囚痴,如下:
Out[51]:
MultiIndex(levels=[['x', 'y', 'z'], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]],
           labels=[[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]])

In [49]: result2.ix['y']                # .ix 等級索引
Out[49]:
    A   B   C   D
4  A4  B4  C4  D4
5  A5  B5  C5  D5
6  A6  B6  C6  D6
7  A7  B7  C7  D7

contact會生成一個copy出革,比較費內(nèi)存。如果要用的話渡讼,最好把所有要拼接的數(shù)據(jù)框放一list中骂束,一次concat所有。像這樣:

frames = [ process_your_file(f) for f in files ]
result = pd.concat(frames)

2. append

和python中l(wèi)ist的append不同成箫,這里的append不改變原來的數(shù)據(jù)框展箱,返回一個拼接后的copy。

In [57]: appended = df1.append([df2, df3])

In [58]: appended
Out[58]:
      A    B    C    D
0    A0   B0   C0   D0
1    A1   B1   C1   D1
2    A2   B2   C2   D2
3    A3   B3   C3   D3
4    A4   B4   C4   D4
5    A5   B5   C5   D5
6    A6   B6   C6   D6
7    A7   B7   C7   D7
8    A8   B8   C8   D8
9    A9   B9   C9   D9
10  A10  B10  C10  D10
11  A11  B11  C11  D11

In [59]: df1
Out[59]:
    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2
3  A3  B3  C3  D3

添加一行:【注】ignore_index=True

可以添加Series或list(放著dicts的list)

In [80]: s2 = pd.Series(['X0', 'X1', 'X2', 'X3'],index=df1.columns)
In [83]: df1_s2 =  df1.append(s2,ignore_index=True)

In [84]: df1_s2
Out[84]:
    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1
2  A2  B2  C2  D2
3  A3  B3  C3  D3
4  X0  X1  X2  X3

dicts = [{'A': 1, 'B': 2, 'C': 3, 'X': 4},
         {'A': 5, 'B': 6, 'C': 7, 'Y': 8}]
result = df1.append(dicts, ignore_index=True)

下面的merge和join是針對數(shù)據(jù)框合并的蹬昌,一般都是列合并混驰。

3. merge

參數(shù)介紹:

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
         left_index=False, right_index=False, sort=True,
         suffixes=('_x', '_y'), copy=True, indicator=False)
         
left: 一個dataframe對象
right: 另一個dataframe對象
how: 可以是'left', 'right', 'outer', 'inner'. 默認為inner。
on: 列名皂贩,兩個dataframe都有的列栖榨。如果不傳參數(shù),
    而且left_index和right_index也等于False明刷,
    則默認把兩者交叉/共有的列作為鏈接鍵(join keys)婴栽。
    可以是一個列名,也可以是包含多個列名的list辈末。
left_on: 左邊dataframe的列會用做keys愚争。可以是列名挤聘,
    或者與dataframe長度相同的矩陣array轰枝。
right_on: 右邊同上。
left_index: 如果為Ture组去,用左側(cè)dataframe的index作為
    連接鍵鞍陨。如果是多維索引,level數(shù)要跟右邊相同才行从隆。
right_index: 右邊同上诚撵。
sort: 對合并后的數(shù)據(jù)框排序缭裆,以連接鍵。
suffixes: 一個tuple砾脑,包字符串后綴幼驶,用來加在重疊的列名后面艾杏。
    默認是('_x','_y')韧衣。
copy: 默認Ture,復(fù)制數(shù)據(jù)购桑。
indicator: 布爾型(True/FALSE)畅铭,或是字符串。
    如果為True勃蜘,合并之后會增加一列叫做'_merge'硕噩。
    是分類數(shù)據(jù),用left_only, right_only, both來標記
    來自左邊缭贡,右邊和兩邊的數(shù)據(jù)炉擅。

示例:

In [4]: left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
   ...:                      'A': ['A0', 'A1', 'A2', 'A3'],
   ...:                      'B': ['B0', 'B1', 'B2', 'B3']})
   ...:

In [6]: right = pd.DataFrame({'key': ['K1', 'K2', 'K3', 'K4'],
   ...:                       'C': ['C0', 'C1', 'C2', 'C3'],
   ...:                       'D': ['D0', 'D1', 'D2', 'D3']})
   ...:

#默認inner合并,只保留共同的部分阳惹。
In [7]: pd.merge(left, right, on='key')
Out[7]:
    A   B key   C   D
0  A1  B1  K1  C0  D0
1  A2  B2  K2  C1  D1
2  A3  B3  K3  C2  D2

#outer方式合并
In [8]: pd.merge(left, right, how='outer', on='key')
Out[8]:
     A    B key    C    D
0   A0   B0  K0  NaN  NaN
1   A1   B1  K1   C0   D0
2   A2   B2  K2   C1   D1
3   A3   B3  K3   C2   D2
4  NaN  NaN  K4   C3   D3

#indicator谍失,用來標示數(shù)據(jù)來源。
In [11]: In [8]: pd.merge(left, right, how='outer', on='key', indicator = 'indicator_colomn')
Out[11]:
     A    B key    C    D indicator_colomn
0   A0   B0  K0  NaN  NaN        left_only
1   A1   B1  K1   C0   D0             both
2   A2   B2  K2   C1   D1             both
3   A3   B3  K3   C2   D2             both
4  NaN  NaN  K4   C3   D3       right_only

4. Join

另一個便捷的合并數(shù)據(jù)框的方法莹汤。

參數(shù)介紹:

DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)

other:一個DataFrame快鱼、Series(要有命名),或者DataFrame組成的list纲岭。
on:列名抹竹,包含列名的list或tuple,或矩陣樣子的列
    (如果是多列止潮,必須有MultiIndex)窃判。
    跟上面的幾種方法一樣,用來指明依據(jù)哪一列進行合并喇闸。
    如果沒有賦值兢孝,則依據(jù)兩個數(shù)據(jù)框的index合并。
how:合并方式仅偎, {‘left’, ‘right’, ‘outer’, ‘inner’},
    默認 ‘left’調(diào)用函數(shù)的數(shù)據(jù)框跨蟹。
lsuffix:字符串。用于左側(cè)數(shù)據(jù)框的重復(fù)列橘沥。
    把重復(fù)列重新命名窗轩,原來的列名+字符串。
    【如果有重復(fù)列座咆,必須添加這個參數(shù)痢艺〔滞荩】
rsuffix:同上。右側(cè)堤舒。
sort:布爾型色建,默認False。如果為True舌缤,將鏈接鍵(on的那列)按字母排序箕戳。

示例:

In [3]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
   ...:                      'B': ['B0', 'B1', 'B2'],
   ...:                      'D': ['D3', 'D4', 'D5']},
   ...:                      index=['K0', 'K1', 'K2'])
   ...:
   ...: right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
   ...:                       'D': ['D0', 'D2', 'D3']},
   ...:                       index=['K0', 'K2', 'K3'])
   ...:
   
In [5]: left.join(right, lsuffix='_left', rsuffix='_right')
Out[5]:
     A   B D_left    C D_right
K0  A0  B0     D3   C0      D0
K1  A1  B1     D4  NaN     NaN
K2  A2  B2     D5   C2      D2

In [8]: left.join(right, on='D', how='outer', lsuffix='_left', rsuffix='_right')
Out[8]:
     D    A    B D_left    C D_right
K0  D3   A0   B0     D3  NaN     NaN
K1  D4   A1   B1     D4  NaN     NaN
K2  D5   A2   B2     D5  NaN     NaN
K2  K0  NaN  NaN    NaN   C0      D0
K2  K2  NaN  NaN    NaN   C2      D2
K2  K3  NaN  NaN    NaN   C3      D3

#對比沒有'on'的情況。對于上面第8行輸出有點兒懵逼国撵。
In [9]: left.join(right, how='outer', lsuffix='_left', rsuffix='_right')
Out[9]:
      A    B D_left    C D_right
K0   A0   B0     D3   C0      D0
K1   A1   B1     D4  NaN     NaN
K2   A2   B2     D5   C2      D2
K3  NaN  NaN    NaN   C3      D3

# 使用默認索引的時候:
In [10]: left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
    ...:                      'B': ['B0', 'B1', 'B2'],
    ...:                      'D': ['D3', 'D4', 'D5']})
    ...: right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
    ...:                       'D': ['D0', 'D2', 'D3']})
    ...:

In [11]: left.join(right, lsuffix='_left', rsuffix='_right')
Out[11]:
    A   B D_left   C D_right
0  A0  B0     D3  C0      D0
1  A1  B1     D4  C2      D2
2  A2  B2     D5  C3      D3

合并數(shù)據(jù)框這些方法大同小異陵吸,選一個能滿足需要就行啦。


數(shù)據(jù)重整

pivot

用于生成一個數(shù)據(jù)透視表介牙。

參數(shù)介紹:

DataFrame.pivot(index=None, columns=None, values=None)[source]

index:字符串或?qū)ο笞吵妫蛇x。列名环础,用來當新數(shù)據(jù)框index的列囚似,可以是多個列名的list。
columns:字符串或?qū)ο笙叩谩A忻幕剑斪鲂聰?shù)據(jù)框的列。
values:字符串或?qū)ο罂蚨迹蛇x搬素。列名,生成新數(shù)據(jù)框的值魏保。
    如果沒有指定熬尺,則使用余下的所有列,會生成等級索引列谓罗。

示例:

In [16]: df = pd.DataFrame({'foo': ['one','one','one','two','two','two'],
    ...:                    'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
    ...:                    'baz': [1, 2, 3, 4, 5, 6]})

In [20]: df
Out[20]:
  bar  baz  foo
0   A    1  one
1   B    2  one
2   C    3  one
3   A    4  two
4   B    5  two
5   C    6  two

In [21]: df.pivot(index='foo', columns='bar', values='baz')
    ...:
Out[21]:
bar  A  B  C
foo
one  1  2  3
two  4  5  6

# 有多列數(shù)值的情況
In [22]: df['baz_2'] = df['baz']*2

In [23]: df.pivot(index='foo', columns='bar')
Out[23]:
    baz       baz_2
bar   A  B  C     A   B   C
foo
one   1  2  3     2   4   6
two   4  5  6     8  10  12

# 另一種選擇數(shù)值value的方法
In [24]: df.pivot(index='foo', columns='bar')['baz_2']
Out[24]:
bar  A   B   C
foo
one  2   4   6
two  8  10  12

升級版pivot:pandas.DataFrame.pivot_table粱哼。有更多的參數(shù)。個人感覺比較雞肋檩咱,復(fù)雜的分類匯總有其他的函數(shù)可用揭措。

stack 和 unstack

另一種重整數(shù)據(jù)的方法。stack和unstack是互逆方式刻蚯。參數(shù)很簡單绊含。直接貼個例子好了

In [41]: df2 = df.pivot(index='foo', columns='bar')['baz_2']
    ...: df2
    ...:
Out[41]:
bar  A   B   C
foo
one  2   4   6
two  8  10  12

In [42]: stacked = df2.stack()

In [43]: stacked
Out[43]:
foo  bar
one  A       2
     B       4
     C       6
two  A       8
     B      10
     C      12
dtype: int64

In [44]: stacked.unstack()
Out[44]:
bar  A   B   C
foo
one  2   4   6
two  8  10  12
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市炊汹,隨后出現(xiàn)的幾起案子躬充,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件充甚,死亡現(xiàn)場離奇詭異以政,居然都是意外死亡,警方通過查閱死者的電腦和手機伴找,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門盈蛮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人技矮,你說我怎么就攤上這事抖誉。” “怎么了穆役?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵寸五,是天一觀的道長梳凛。 經(jīng)常有香客問我耿币,道長,這世上最難降的妖魔是什么韧拒? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任淹接,我火速辦了婚禮,結(jié)果婚禮上叛溢,老公的妹妹穿的比我還像新娘塑悼。我一直安慰自己,他們只是感情好楷掉,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布厢蒜。 她就那樣靜靜地躺著,像睡著了一般烹植。 火紅的嫁衣襯著肌膚如雪斑鸦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天草雕,我揣著相機與錄音巷屿,去河邊找鬼。 笑死墩虹,一個胖子當著我的面吹牛嘱巾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播诫钓,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼旬昭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了菌湃?” 一聲冷哼從身側(cè)響起问拘,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后场梆,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墅冷,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年或油,在試婚紗的時候發(fā)現(xiàn)自己被綠了寞忿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡顶岸,死狀恐怖腔彰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辖佣,我是刑警寧澤霹抛,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站卷谈,受9級特大地震影響杯拐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜世蔗,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一端逼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧污淋,春花似錦顶滩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赁豆,卻和暖如春仅醇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背歌憨。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工着憨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人务嫡。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓甲抖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親心铃。 傳聞我的和親對象是個殘疾皇子准谚,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

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