看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在数据采集过程中,由于采集的顺序不同,得到不同的数据,但它们的内容是一样的,这时就需要我们将它们识别出来。本例,我们看看 pandas 如何将不同顺序但内容一样的数据添加相同的序号。
在 pandas DataFrame 中有两列:“a”和“b”:
import pandas as pd
import io
data = '''
a b
1 2
4 3
2 1
3 4
5 6
4 7
'''
df = pd.read_csv(io.StringIO(data), sep=r'\s+')
df
# ...
需要在 df 中添加名为“no”的第三列,如果值相同(可以按不同顺序),则该列将为从1开始的一对提供一个数字,并且每次遇到新的对(至少有一个值不可见的对)时,它都应该递增。如果该对没有其他出现,该对内容继续增加1。即:
'''
a b no
1 2 1
4 3 2
2 1 1
3 4 2
5 6 3
4 7 4
'''
我们先将两列 DataFrame 转为一个集合序列,因为集合内的元素没有顺序,再可以利用 pd.factorize() 将因子化,得到每个组合的序号,然后利用这个因子化序号来充将 no 列的内容。
将 a、b 两列转为一个每个元素为集合的序列,这里用到了内置 frozenset 冻结集合,因为 set 不可哈希,在接下来的因子化过程中不能进行操作。即:
s = df.apply(frozenset, axis=1)
s
'''
0 (1, 2)
1 (3, 4)
2 (1, 2)
3 (3, 4)
4 (5, 6)
5 (4, 7)
dtype: object
'''
这样得到的是一个冻结集合序列:
s.map(type)
'''
0 <class 'frozenset'>
1 <class 'frozenset'>
2 <class 'frozenset'>
3 <class 'frozenset'>
4 <class 'frozenset'>
5 <class 'frozenset'>
dtype: object
'''
原数据中不同顺序的的内容也会被度为相同:
s.value_counts()
'''
(1, 2) 2
(3, 4) 2
(5, 6) 1
(4, 7) 1
Name: count, dtype: int64
'''
接下来因子化:
pd.factorize(s)
'''
(array([0, 1, 2, 3, 4, 5]),
Index([(1, 2), (4, 3), (2, 1), (3, 4), (5, 6), (4, 7)], dtype='object'))
'''
得到了一个元组,第一个元素是它们的序号,相同的内容序号相同。
最后,我们取这个元组的第一个元素,再向量化加 1 就得到了结果。
df.assign(no=pd.factorize(s)[0] + 1)
'''
a b no
0 1 2 1
1 4 3 2
2 2 1 1
3 3 4 2
4 5 6 3
5 4 7 4
'''
最终完成了需求。
相似案例:pandas 相同的行赋同一个值。
(完)
更新时间:2024-08-18 16:18:10 标签:pandas python 序号