看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
将逗号分隔的字符串数据拆分为多个列可以应用于许多场景。比如当你从文件或数据库中读取数据时,有时会遇到一列中包含多个值的情况。逗号分隔的字符串是一种常见的格式。通过将这样的字符串拆分成多个列,可以更容易地对数据进行分析和处理。本例,我们看一个特别的相关的案例。
我们的示例数据如下:
import pandas as pd
import io
data ='''
a b c1 c2 c3 c4
A W 1,2,3 1,2 1,3,3 g
B X 1,2,3,4,5 k 1,4,7 h
'''
df = pd.read_csv(io.StringIO(data),sep=r'\s+')
df
# ...
将 c1 按逗号拆分,爆炸为一行一行数据,然后将 c1 后边的有逗号的扩展成行,没逗号的只写在第一行。
最终效果如:
'''
a b c1 c2 c3 c4
0 A W 1 1 1 g
1 A W 2 2 3
2 A W 3 3
3 B X 1 k 1 h
4 B X 2 4
5 B X 3 7
6 B X 4
7 B X 5
'''
先将 DataFrame 中有逗号的值分拆转为列表,接下来我们对 c1 进行爆炸,就得到了整个数据的基本框架,在这个框架上我们修改调整数据。
将 a、b 两列设置为索引,这样我们就只处需要处理的逻辑(当然 c1 也不需要再处理了,也可以设置为索引),在最后需要处理完成了再重置回来。
写一个数据处理函数,用索引分组后的 transform() 来应用,因为 transform() 返回的是对每个列的处理,返回的相同形状的数据。
关键是这个函数的逻辑:
先将有逗号的值拆分成列表:
df.map(lambda x: x.split(',') if ',' in x else x)
'''
a b c1 c2 c3 c4
0 A W [1, 2, 3] [1, 2] [1, 3, 3] g
1 B X [1, 2, 3, 4, 5] k [1, 4, 7] h
'''
爆炸 c1 列,设置索引:
(
df.map(lambda x: x.split(',') if ',' in x else x)
.explode('c1')
.set_index(['a', 'b'])
)
'''
c1 c2 c3 c4
a b
A W 1 [1, 2] [1, 3, 3] g
W 2 [1, 2] [1, 3, 3] g
W 3 [1, 2] [1, 3, 3] g
B X 1 k [1, 4, 7] h
X 2 k [1, 4, 7] h
X 3 k [1, 4, 7] h
X 4 k [1, 4, 7] h
X 5 k [1, 4, 7] h
'''
分组,按思路逻辑编写处理函数:
def func(s: pd.Series):
first = s.iloc[0]
if s.name == 'c1':
return s
elif isinstance(first, list):
space_len = len(s) - len(first)
values = first + ['']*space_len
return values
else:
values = [first] + ['']*(len(s)-1)
return values
(
df.map(lambda x: x.split(',') if ',' in x else x)
.explode('c1')
.set_index(['a', 'b'])
.groupby(level=[0, 1])
.transform(func)
.reset_index()
)
# ...
这样就得到了最终的需求结果。
(完)
更新时间:2024-08-18 16:24:04 标签:pandas python 扩展