主要內(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