看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
需求如下,将 A、B 两列组合进行分组,同组内的数据显示在同一行,有多少条数据就放多少列:
import pandas as pd
from io import StringIO
# 原数据
data = '''
A B C D
a b1 c 2001
a b1 c 2003
a b1 c 2005
a b2 c 2001
a b2 c 2002
a b2 c 2003
a b2 c 2004
'''
df = pd.read_csv(StringIO(data), sep=r'\s+')
df
# 转换后
'''
D 2001 2002 2003 2004 2005
A B C
a b1 c 2001.0 NaN 2003.0 NaN 2005.0
b2 c 2001.0 2002.0 2003.0 2004.0 NaN
'''
经过我们的观察,以上需求中数据的变化符合数据透视的规则。直接进行数据透视:
df.pivot(index=['A', 'B', 'C'], columns='D', values='D')
'''
D 2001 2002 2003 2004 2005
A B C
a b1 c 2001.0 NaN 2003.0 NaN 2005.0
b2 c 2001.0 2002.0 2003.0 2004.0 NaN
'''
基本上实现了需求,不过还需要再进行一些处理。我们可以更换一下思路,先按 ['A', 'B', 'C'] 进行 groupby 分组,再将分组后的数据用逗号隔开:
(
df.groupby(['A', 'B', 'C'])
.apply(lambda x: ','.join(x.D.astype(str)))
)
'''
A B C
a b1 c 2001,2003,2005
b2 c 2001,2002,2003,2004
dtype: object
'''
再将逗号隔开的字符用 .str.split() 展示为列:
(
df.groupby(['A', 'B', 'C'])
.apply(lambda x: ','.join(x.D.astype(str)))
.str.split(',', expand=True)
)
'''
D 2001 2002 2003 2004 2005
A B C
a b1 c 2001.0 NaN 2003.0 NaN 2005.0
b2 c 2001.0 2002.0 2003.0 2004.0 NaN
'''
这样就得到了需求所要求的效果。
(完)
注:此案例收录在《深入浅出Pandas:利用Python进行数据处理与分析》17.2.3 小节。
更新时间:2024-08-18 16:12:20 标签:pandas python 转换