看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
文本是数据处理中非常重要的数据部分,pandas 具有强大的文本数据处理能力,本案例文本数据处理方面的。本例中,有一列文本数据,每个文本与上一行文本用特定字符表示从属关系,需要我们解析出该行末级的上一级是什么。
以下为数据,是一个树状的层级结构,为了方便观察,我们用——
代替了空格等内容:
# 数据,为了方便观察空格用——代替
'''
class_
A
——B1
——B2
————C1
——B3
————C2
————C3
'''
数据中,如第二三行,都属于 A,C1 属于 B2,我们用字母表示,但实际中是具体的不特定的字符。
需求为解析出当前行所在的上级,如果已经是根级则它上级仍然是根级。
读取数据:
df = pd.read_clipboard()
df.class_
# ...
先将以上文本结构化,用分隔符号拆解,会生成一个一个层级为一列的数据表,然后对除了最后级外将空缺的上一级内容用上一级行该前方值填充。
然后按行进行处理,剔除每行的缺失值,除了根级(剔除缺失值后长度为 1)外,取其右边第二个值,就是我们要的上级内容。
先将文拆开,形成一个表示层级的结构化表格:
(
df.class_.str.split('——', expand=True)
.replace({'': None})
)
'''
0 1 2
0 A None None
1 None B1 None
2 None B2 None
3 None None C1
4 None B3 None
5 None None C2
6 None None C3
'''
除了最后一列名进行前值填充:
(
df.class_.str.split('——', expand=True)
.replace({'': None})
.apply(lambda x: x if x.name == 2 else x.ffill()) # <--
)
'''
0 1 2
0 A None None
1 A B1 None
2 A B2 None
3 A B2 C1
4 A B3 None
5 A B3 C2
6 A B3 C3
'''
增加一个辅助列,用于显示剔除缺失值后的层级列表:
(
df.class_.str.split('——', expand=True)
.replace({'': None})
.apply(lambda x: x if x.name == 2 else x.ffill())
.assign(foo=lambda x: x.apply(lambda s: s.dropna().to_list(), axis=1))
)
'''
0 1 2 foo
0 A None None [A]
1 A B1 None [A, B1]
2 A B2 None [A, B2]
3 A B2 C1 [A, B2, C1]
4 A B3 None [A, B3]
5 A B3 C2 [A, B3, C2]
6 A B3 C3 [A, B3, C3]
'''
针对这个层级列表增加结果列,如果长度为 1 则为根级,否则取列表的倒数第二个,就是它的上级。
(
df.class_.str.split('——', expand=True)
.replace({'': None})
.apply(lambda x: x if x.name == 2 else x.ffill())
.assign(foo=lambda x: x.apply(lambda s: s.dropna().to_list(), axis=1))
.assign(res=lambda x: x.foo.apply(lambda s: s[-2] if len(s)>1 else None))
)
'''
0 1 2 foo res
0 A None None [A] None
1 A B1 None [A, B1] A
2 A B2 None [A, B2] A
3 A B2 C1 [A, B2, C1] B2
4 A B3 None [A, B3] A
5 A B3 C2 [A, B3, C2] B3
6 A B3 C3 [A, B3, C3] B3
'''
这样就完成了需求。
(完)
更新时间:2024-08-18 15:56:19 标签:pandas python 层级