为python数据帧内的重复项添加增量

2024-05-14 18:57:59 发布

您现在位置: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开始。真正的问题是,在这个数据集中有重复的BraveCKSWAGRAM值,所以它不能适当地增加和复制BLUBEWKSWAANG3,因为我不能在将函数应用到整个数据集的中间更新历史。p>

是否有一些优雅的pythonic方法可以做到这一点,但我无法完全理解,或者这是一种在数据帧中进行迭代确实有意义的场景


Tags: 数据函数dfifmainexistsblue历史
1条回答
网友
1楼 · 发布于 2024-05-14 18:57:59

我不完全确定您想要实现什么,但您可以在此过程中更新blacklistblacklist只是指向实际列表数据的指针。如果您通过在return语句之前添加blacklist.append(summary)来稍微修改gen_summary

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循环和更快的查找的情况下生成相同的结果

相关问题 更多 >

    热门问题