pandas 将索引附加到重复对

jfewjypa  于 2022-12-21  发布在  其他
关注(0)|答案(3)|浏览(134)

我有一个交易列表包含一个标题(H)和细节(D)行。H行和D行必须有一个"发票编号"列匹配,但是如果在同一天有几笔交易,有时会有重复的发票号码。我想做的是在发票号码的末尾添加一个索引,以防止任何重复。下面是我的数据框的可视化表示和我要完成的任务。我在示例中使用字母作为索引来帮助查看差异,但数字索引也可以工作,只是试图消除重复命名。
我不确定我是否必须迭代每个记录,或者是否有一些事情可以作为一个整体来做。

    • 原始文件**

| 识别号|类型|发票号码|数量|
| - ------| - ------| - ------| - ------|
| 一|高|博伯12192022|十点整|
| 一|D级|小标题:|十点整|
| 二|高|约耳12182022|三十点整|
| 二|D级|约耳12182022|三十点整|
| 03|高|小标题:|十五点整|
| 03| D级|小标题:|十五点整|
| 四|高|小标题:|七十五分|
| 四|D级|小标题:|二十五点整|
| 四|D级|小标题:|二十五点整|
| 四|D级|小标题:|二十五点整|

    • 预期结果**

| 识别号|类型|发票号码|数量|
| - ------| - ------| - ------| - ------|
| 一|高|编号:12192022A|十点整|
| 一|D级|博伯12192022A|十点整|
| 二|高|约耳12182022|三十点整|
| 二|D级|约耳12182022|三十点整|
| 03|高|博伯12192022B|十五点整|
| 03| D级|博伯12192022B|十五点整|
| 四|高|BOB12192022C型|七十五分|
| 四|D级|BOB12192022C型|二十五点整|
| 四|D级|BOB12192022C型|二十五点整|
| 四|D级|BOB12192022C型|二十五点整|

wvyml7n5

wvyml7n51#

你应该加一个列来表示重名,这样就容易多了,否则在计算时会出现追溯的麻烦

df['dup'] = df.groupby(['type, invoice_number'])['invoice_number'].cumcount()

如果dup值为而不是0,则可以轻松识别任何invoice是否重复

dy2hfwbg

dy2hfwbg2#

您可以使用groupby.transform()进行一些算术运算和整数到字符的转换:

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {
        "type": ["H", "D", "H", "D", "H", "D"],
        "invoice": ["ABC", "ABC", "DEF", "DEF", "ABC", "ABC"],
        "amount": ["10", "10", "20", "20", "10", "10"],
    }
)

df["suffix"] = df.groupby("invoice")["type"].transform(
    lambda x: ["_" + chr(65 + int(np.floor(i / 2))) for i in range(len(x))]
)
df["invoice"] = df["invoice"] + df["suffix"]

结果:

type invoice amount suffix
0    H   ABC_A     10     _A
1    D   ABC_A     10     _A
2    H   DEF_A     20     _A
3    D   DEF_A     20     _A
4    H   ABC_B     10     _B
5    D   ABC_B     10     _B

注意,这种方法假设每个事务有2个条目。

oknwwptz

oknwwptz3#

更新:

df['invoice number'] = (df['invoice number'] + 
                        (df[df.duplicated(['type', 'invoice number'], keep=False)].groupby('ID').ngroup())
                              .map(dict(enumerate(ascii_uppercase)))).fillna(df['invoice number'])

输出:

ID type invoice number  amount
0   1    H   BOB12192022A    10.0
1   1    D   BOB12192022A    10.0
2   2    H    JOE12182022    30.0
3   2    D    JOE12182022    30.0
4   3    H   BOB12192022B    15.0
5   3    D   BOB12192022B    15.0
6   4    H   BOB12192022C    75.0
7   4    D   BOB12192022C    25.0
8   4    D   BOB12192022C    25.0
9   4    D   BOB12192022C    25.0

试试这个:

from string import ascii_uppercase

df['invoice number'] += np.where(df.groupby(['invoice number'])['invoice number'].transform('count') > 2,
                                 df.groupby(['type', 'invoice number']).cumcount().map(dict(enumerate(ascii_uppercase))), '')

输出:

type invoice number  amount
0    H   BOB12192022A    10.0
1    D   BOB12192022A    10.0
2    H    JOE12182022    30.0
3    D    JOE12182022    30.0
4    H   BOB12192022B    15.0
5    D   BOB12192022B    15.0
6    H   BOB12192022C    50.0
7    D   BOB12192022C    50.0

相关问题