看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
将一个数据按组左右拼接是一种常用的数据处理技术。这种技术可以用于多种场景,下面是一些常见的使用场景:
这些是将数据按组左右拼接的一些常见使用场景,不同的数据处理需求可能还有其他使用场景。
接下来,我们用 pandas 来完成相关的一个操作示例。
我们有以下两个数据:
import pandas as pd
from io import StringIO
data1 = '''
name
Liver
Arry
Ack
Eorge
Acob
Lfie
Oscar
Leo
Logan
Thomas
'''
data2 = '''
team name Q1 Q2
A Ack 57 60
A Lfie 9 10
A Oscar 77 9
B Acob 61 95
B Leo 17 4
B Logan 9 89
B Thomas 80 48
C Arry 36 37
C Eorge 93 96
E Liver 89 21
'''
df1 = pd.read_csv(StringIO(data1))
df2 = pd.read_csv(StringIO(data2), sep=r'\s+')
需求需要将 df2 按 team 分组,分组后以 name 为标准将数据左右拼接起来,最后按 df1 中 name 的顺序排列。即结果为:
'''
team Q1 Q2 team Q1 Q2 team Q1 Q2 team Q1 Q2
name
Liver A 0 0 B 0 0 C 0 0 E 89 21
Arry A 0 0 B 0 0 C 36 37 E 0 0
Ack A 57 60 B 0 0 C 0 0 E 0 0
Eorge A 0 0 B 0 0 C 93 96 E 0 0
Acob A 0 0 B 61 95 C 0 0 E 0 0
Lfie A 9 10 B 0 0 C 0 0 E 0 0
Oscar A 77 9 B 0 0 C 0 0 E 0 0
Leo A 0 0 B 17 4 C 0 0 E 0 0
Logan A 0 0 B 9 89 C 0 0 E 0 0
Thomas A 0 0 B 80 48 C 0 0 E 0 0
'''
在 df2 中,将 name 列设置为索引,然后按 team 分组,分组后为不同组组成的子 DataFrame,将这些子 DataFrame 横向拼接起来,最后再对索引以 df1 的 name 列进行重排序。
将 df2 的 name 列设置为索引:
df2.set_index('name')
'''
team Q1 Q2
name
Ack A 57 60
Lfie A 9 10
Oscar A 77 9
Acob B 61 95
Leo B 17 4
Logan B 9 89
Thomas B 80 48
Arry C 36 37
Eorge C 93 96
Liver E 89 21
'''
接下来,分组、拼接:
(
df2.set_index('name')
.groupby('team')
.pipe(lambda g: pd.concat([d for _,d in g], axis=1))
)
'''
team Q1 Q2 team Q1 Q2 team Q1 Q2 team Q1 Q2
name
Ack A 57.0 60.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
Lfie A 9.0 10.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
Oscar A 77.0 9.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
Acob NaN NaN NaN B 61.0 95.0 NaN NaN NaN NaN NaN NaN
Leo NaN NaN NaN B 17.0 4.0 NaN NaN NaN NaN NaN NaN
Logan NaN NaN NaN B 9.0 89.0 NaN NaN NaN NaN NaN NaN
Thomas NaN NaN NaN B 80.0 48.0 NaN NaN NaN NaN NaN NaN
Arry NaN NaN NaN NaN NaN NaN C 36.0 37.0 NaN NaN NaN
Eorge NaN NaN NaN NaN NaN NaN C 93.0 96.0 NaN NaN NaN
Liver NaN NaN NaN NaN NaN NaN NaN NaN NaN E 89.0 21.0
'''
已经完成了拼接,接下来我们将所有的 team 填充完整,并将缺失值修改为 0:
(
df2.set_index('name')
.groupby('team')
.pipe(lambda g: pd.concat([d for _,d in g], axis=1))
.assign(team=lambda d: d.team.ffill().bfill() )
.fillna(0)
)
'''
team Q1 Q2 team Q1 Q2 team Q1 Q2 team Q1 Q2
name
Ack A 57.0 60.0 B 0.0 0.0 C 0.0 0.0 E 0.0 0.0
Lfie A 9.0 10.0 B 0.0 0.0 C 0.0 0.0 E 0.0 0.0
Oscar A 77.0 9.0 B 0.0 0.0 C 0.0 0.0 E 0.0 0.0
Acob A 0.0 0.0 B 61.0 95.0 C 0.0 0.0 E 0.0 0.0
Leo A 0.0 0.0 B 17.0 4.0 C 0.0 0.0 E 0.0 0.0
Logan A 0.0 0.0 B 9.0 89.0 C 0.0 0.0 E 0.0 0.0
Thomas A 0.0 0.0 B 80.0 48.0 C 0.0 0.0 E 0.0 0.0
Arry A 0.0 0.0 B 0.0 0.0 C 36.0 37.0 E 0.0 0.0
Eorge A 0.0 0.0 B 0.0 0.0 C 93.0 96.0 E 0.0 0.0
Liver A 0.0 0.0 B 0.0 0.0 C 0.0 0.0 E 89.0 21.0
'''
最后,按 df1 提供的数据重新排序,并将 Q1 和 Q2 列的类型修改为整型:
(
df2.set_index('name')
.groupby('team')
.pipe(lambda g: pd.concat([d for _,d in g], axis=1))
.assign(team=lambda d: d.team.ffill().bfill() )
.fillna(0)
.reindex(df1.name)
.astype({col:int for col in ['Q1', 'Q2']})
)
'''
team Q1 Q2 team Q1 Q2 team Q1 Q2 team Q1 Q2
name
Liver A 0 0 B 0 0 C 0 0 E 89 21
Arry A 0 0 B 0 0 C 36 37 E 0 0
Ack A 57 60 B 0 0 C 0 0 E 0 0
Eorge A 0 0 B 0 0 C 93 96 E 0 0
Acob A 0 0 B 61 95 C 0 0 E 0 0
Lfie A 9 10 B 0 0 C 0 0 E 0 0
Oscar A 77 9 B 0 0 C 0 0 E 0 0
Leo A 0 0 B 17 4 C 0 0 E 0 0
Logan A 0 0 B 9 89 C 0 0 E 0 0
Thomas A 0 0 B 80 48 C 0 0 E 0 0
'''
这样就完成了需求。
(完)
更新时间:2024-08-18 16:11:59 标签:pandas python 拼接