主要內(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:要粘在哪個(gè)軸上。默認(rèn)0,粘貼行。
join:默認(rèn)outer,合集;inner,交集。
ignore_index:布爾型,默認(rèn)False。如果為T(mén)ure的話(huà),會(huì)重新分配index從0...n-1。
keys:一個(gè)序列,默認(rèn)None。建立等級(jí)索引,作為最外層的level。
levels:序列sequences構(gòu)成的list,默認(rèn)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 等級(jí)索引
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會(huì)生成一個(gè)copy,比較費(fèi)內(nèi)存。如果要用的話(huà),最好把所有要拼接的數(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不改變?cè)瓉?lái)的數(shù)據(jù)框,返回一個(gè)拼接后的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是針對(duì)數(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: 一個(gè)dataframe對(duì)象
right: 另一個(gè)dataframe對(duì)象
how: 可以是'left', 'right', 'outer', 'inner'. 默認(rèn)為inner。
on: 列名,兩個(gè)dataframe都有的列。如果不傳參數(shù),
而且left_index和right_index也等于False,
則默認(rèn)把兩者交叉/共有的列作為鏈接鍵(join keys)。
可以是一個(gè)列名,也可以是包含多個(gè)列名的list。
left_on: 左邊dataframe的列會(huì)用做keys??梢允橇忻?,
或者與dataframe長(zhǎng)度相同的矩陣array。
right_on: 右邊同上。
left_index: 如果為T(mén)ure,用左側(cè)dataframe的index作為
連接鍵。如果是多維索引,level數(shù)要跟右邊相同才行。
right_index: 右邊同上。
sort: 對(duì)合并后的數(shù)據(jù)框排序,以連接鍵。
suffixes: 一個(gè)tuple,包字符串后綴,用來(lái)加在重疊的列名后面。
默認(rèn)是('_x','_y')。
copy: 默認(rèn)Ture,復(fù)制數(shù)據(jù)。
indicator: 布爾型(True/FALSE),或是字符串。
如果為T(mén)rue,合并之后會(huì)增加一列叫做'_merge'。
是分類(lèi)數(shù)據(jù),用left_only, right_only, both來(lái)標(biāo)記
來(lái)自左邊,右邊和兩邊的數(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']})
...:
#默認(rèn)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,用來(lái)標(biāo)示數(shù)據(jù)來(lái)源。
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
另一個(gè)便捷的合并數(shù)據(jù)框的方法。
參數(shù)介紹:
DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)
other:一個(gè)DataFrame、Series(要有命名),或者DataFrame組成的list。
on:列名,包含列名的list或tuple,或矩陣樣子的列
(如果是多列,必須有MultiIndex)。
跟上面的幾種方法一樣,用來(lái)指明依據(jù)哪一列進(jìn)行合并。
如果沒(méi)有賦值,則依據(jù)兩個(gè)數(shù)據(jù)框的index合并。
how:合并方式, {‘left’, ‘right’, ‘outer’, ‘inner’},
默認(rèn) ‘left’調(diào)用函數(shù)的數(shù)據(jù)框。
lsuffix:字符串。用于左側(cè)數(shù)據(jù)框的重復(fù)列。
把重復(fù)列重新命名,原來(lái)的列名+字符串。
【如果有重復(fù)列,必須添加這個(gè)參數(shù)?!?rsuffix:同上。右側(cè)。
sort:布爾型,默認(rèn)False。如果為T(mén)rue,將鏈接鍵(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
#對(duì)比沒(méi)有'on'的情況。對(duì)于上面第8行輸出有點(diǎn)兒懵逼。
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
# 使用默認(rèn)索引的時(shí)候:
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ù)框這些方法大同小異,選一個(gè)能滿(mǎn)足需要就行啦。
數(shù)據(jù)重整
pivot
用于生成一個(gè)數(shù)據(jù)透視表。
參數(shù)介紹:
DataFrame.pivot(index=None, columns=None, values=None)[source]
index:字符串或?qū)ο?,可選。列名,用來(lái)當(dāng)新數(shù)據(jù)框index的列,可以是多個(gè)列名的list。
columns:字符串或?qū)ο?。列名,?dāng)做新數(shù)據(jù)框的列。
values:字符串或?qū)ο?,可選。列名,生成新數(shù)據(jù)框的值。
如果沒(méi)有指定,則使用余下的所有列,會(huì)生成等級(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
升級(jí)版pivot:pandas.DataFrame.pivot_table。有更多的參數(shù)。個(gè)人感覺(jué)比較雞肋,復(fù)雜的分類(lèi)匯總有其他的函數(shù)可用。
stack 和 unstack
另一種重整數(shù)據(jù)的方法。stack和unstack是互逆方式。參數(shù)很簡(jiǎn)單。直接貼個(gè)例子好了
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