python - 在 python 数据框中为重复项添加增量
问题描述
我正在寻找连接数据框中的两列,并且在有重复的地方,在末尾附加一个整数。这里的问题是我将继续接收数据源,并且增量需要了解生成的历史值而不是重用它们。
我一直在尝试使用 apply 函数来执行此操作,但是当单个接收到的数据集中有重复项时我遇到了问题,而且我无法在不遍历数据帧的情况下找到一种方法来执行此操作(这通常是不受欢迎的)。
我已经做到了这一点:
import pandas as pd
def gen_summary(color, car, blacklist):
exists = True
increment = 0
summary = color + car
while exists:
if summary in blacklist:
increment += 1
summary = color + car + str(increment) # Append increment if in burn list
else:
exists = False # Exit this loop
return summary
def main():
blacklist = ['RedToyota', 'BlueVolkswagon', 'BlueVolkswagon1', 'BlueVolkswagon2']
df = pd.DataFrame(
{'color': ['Red', 'Blue', 'Blue', 'Green'],
'car': ['Toyota', 'Volkswagon', 'Volkswagon', 'Hyundai'],
'summary': ['', '', '', '']}
)
#print(df)
df["summary"] = df.apply(lambda x: gen_summary(x['color'], x['car'], blacklist), axis=1)
print(df)
if __name__ == "__main__":
main()
输出:
color car summary
0 Red Toyota RedToyota1
1 Blue Volkswagon BlueVolkswagon3
2 Blue Volkswagon BlueVolkswagon3
3 Green Hyundai GreenHyundai
请注意,之前的数据馈送中使用了 BlueVolkswagon1 和 BlueVolkswagon2,因此这里必须从 3 开始。真正的问题是,仅此数据集中有重复的 BlueVolkswagon 值,因此它不会正确递增并重复 BlueVolkswagon3,因为我无法在将函数应用于整个数据集的过程中更新历史记录。
是否有一些优雅的 pythonic 方法可以做到这一点,我无法绕开我的脑袋,或者这是一个迭代数据框确实有意义的场景?
解决方案
我不完全确定您想要实现什么,但您可以blacklist
在此过程中进行更新。blacklist
只是指向实际列表数据的指针。如果你通过在语句之前gen_summary
添加稍微修改blacklist.append(summary)
return
def gen_summary(color, car, blacklist):
...
exists = False # Exit this loop
blacklist.append(summary)
return summary
你会得到以下结果
color car summary
0 Red Toyota RedToyota1
1 Blue Volkswagon BlueVolkswagon3
2 Blue Volkswagon BlueVolkswagon4
3 Green Hyundai GreenHyundai
分组会更有效率。这应该产生相同的结果:
def gen_summary(ser, blacklist):
color_car = ser.iat[0]
summary = color_car
increment = 0
exists = True
while exists:
if summary in blacklist:
increment += 1
summary = color_car + str(increment) # Append increment if in burn list
else:
exists = False # Exit this loop
return ([color_car + ('' if increment == 0 else str(increment))]
+ [color_car + str(i + increment) for i in range(1, len(ser))])
df['summary'] = df['color'] + df['car']
df['summary'] = df.groupby(['color', 'car']).transform(gen_summary, blacklist)
这就是你要找的结果吗?如果是,我想添加一个优化您的方法的建议:使用字典而不是列表blacklist
:
def gen_summary(color, car, blacklist):
key = color + car
num = blacklist.get(key, -1) + 1
blacklist[key] = num
return key if num == 0 else f'{key}{num}'
blacklist = {'RedToyota': 0, 'BlueVolkswagon': 2}
或分组
def gen_summary(ser, blacklist):
key = ser.iat[0]
num = blacklist.get(key, -1) + 1
return ([f'{key}{"" if num == 0 else num}']
+ [f'{key}{i + num}' for i in range(1, len(ser))])
blacklist = {'RedToyota': 0, 'BlueVolkswagon': 2}
df['summary'] = df['color'] + df['car']
df['summary'] = df.groupby(['color', 'car']).transform(gen_summary, blacklist)
while
如果没有-loop 和更快的查找,应该会产生相同的结果。
推荐阅读
- node.js - 将 youtube-dl 脚本上传到 Google Cloud 存储
- python - 更新用户模型时如何更新我的 UserProfile 模型 Django
- java - 从另一个类访问对象数组
- excel-formula - 索引单元格参考
- python - wn.synset('whale.n.01') 返回错误的同义词集
- harp.gl - 如何在 harp.gl 中绘制地下层并将相机设置为它
- spamassassin - 无法使 SpamAssassin 主题规则生效
- python - 单击其中一个时,在运行相应 python 文件的 pyqt4 中构建按钮
- javascript - 对本地存储进行排序(数组/字符串化)
- sql-server - VB.NET 执行循环查询并在 1 个 datagridview 中显示其结果