python 数据框按行拼接_Python数据分析_Pandas02_数据框的合并和重整

本文详细介绍了Python中数据框的拼接方法,包括concat、append、merge和join,以及数据重整操作pivot。通过示例展示了如何使用这些函数进行数据整合和重塑,适用于数据处理和分析场景。
摘要由CSDN通过智能技术生成

主要内容:

数据拼接:join、merge、contact、append

数据重整:reshape -- stuck、unstuck

数据透视表:pivot tables

数据拼接

1. concat

参数介绍:

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构成的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,比较费内存。如果要用的话,最好把所有要拼接的数据框放一list中,一次concat所有。像这样:

frames = [ process_your_file(f) for f in files ]

result = pd.concat(frames)

2. append

和python中list的append不同,这里的append不改变原来的数据框,返回一个拼接后的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是针对数据框合并的,一般都是列合并。

3. merge

参数介绍:

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都有的列。如果不传参数,

而且left_index和right_index也等于False,

则默认把两者交叉/共有的列作为链接键(join keys)。

可以是一个列名,也可以是包含多个列名的list。

left_on: 左边dataframe的列会用做keys。可以是列名,

或者与dataframe长度相同的矩阵array。

right_on: 右边同上。

left_index: 如果为Ture,用左侧dataframe的index作为

连接键。如果是多维索引,level数要跟右边相同才行。

right_index: 右边同上。

sort: 对合并后的数据框排序,以连接键。

suffixes: 一个tuple,包字符串后缀,用来加在重叠的列名后面。

默认是('_x','_y')。

copy: 默认Ture,复制数据。

indicator: 布尔型(True/FALSE),或是字符串。

如果为True,合并之后会增加一列叫做'_merge'。

是分类数据,用left_only, right_only, both来标记

来自左边,右边和两边的数据。

示例:

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,用来标示数据来源。

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

另一个便捷的合并数据框的方法。

参数介绍:

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

other:一个DataFrame、Series(要有命名),或者DataFrame组成的list。

on:列名,包含列名的list或tuple,或矩阵样子的列

(如果是多列,必须有MultiIndex)。

跟上面的几种方法一样,用来指明依据哪一列进行合并。

如果没有赋值,则依据两个数据框的index合并。

how:合并方式, {‘left’, ‘right’, ‘outer’, ‘inner’},

默认 ‘left’调用函数的数据框。

lsuffix:字符串。用于左侧数据框的重复列。

把重复列重新命名,原来的列名+字符串。

【如果有重复列,必须添加这个参数。】

rsuffix:同上。右侧。

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

合并数据框这些方法大同小异,选一个能满足需要就行啦。

数据重整

pivot

用于生成一个数据透视表。

参数介绍:

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

index:字符串或对象,可选。列名,用来当新数据框index的列,可以是多个列名的list。

columns:字符串或对象。列名,当做新数据框的列。

values:字符串或对象,可选。列名,生成新数据框的值。

如果没有指定,则使用余下的所有列,会生成等级索引列。

示例:

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

# 有多列数值的情况

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

# 另一种选择数值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。有更多的参数。个人感觉比较鸡肋,复杂的分类汇总有其他的函数可用。

stack 和 unstack

另一种重整数据的方法。stack和unstack是互逆方式。参数很简单。直接贴个例子好了

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值