【问题标题】:find duplicated groups in dataframe在数据框中查找重复的组
【发布时间】:2020-05-21 21:40:06
【问题描述】:

我有一个如下所述的数据框,我需要根据列 - value1、value2 和 value3 找出重复的组(组应按 id 分组)。 我需要用 true 填充“重复”列 如果组出现在表中的其他位置,如果组是唯一的,则用 false 填充。

注意:每个组都有不同的 id。

df = pd.DataFrame({'id': ['A', 'A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C', 'D', 'D', 'D'],
                   'value1': ['1', '2', '3', '4', '1', '2', '1', '2', '3', '4', '1', '2', '3'],
                   'value2': ['1', '2', '3', '4', '1', '2', '1', '2', '3', '4', '1', '2', '3'],
                   'value3': ['1', '2', '3', '4', '1', '2', '1', '2', '3', '4', '1', '2', '3'],
                   'duplicated' : [] 
                   })

预期结果是:

我试过这个,但如果是比较行,我需要比较组(按 id 分组)

import pandas as pd
data = pd.read_excel('C:/Users/path/Desktop/example.xlsx')

# False : Mark all duplicates as True.
data['duplicates'] = data.duplicated(subset= ["value1","value2","value3"], keep=False)

data.to_excel('C:/Users/path/Desktop/example_result.xlsx',index=False)

我得到了:

注意:两组中记录的顺序无关紧要

【问题讨论】:

  • 订单重要吗?比如C组中,1和2的行互换位置,是否还是“重复”?
  • @Ben.T 组中行的顺序无关紧要
  • @ncica 让它变得有点复杂。
  • @DontKnowMuchButGettingBetter,对不起,这是我的错误,代码是正确的,我没有注意到我在错误的函数中编写了那部分代码,tnx 提示:)
  • @ncica:不客气,但以后请通知我们。我们是提供帮助的志愿者。请注意,如果您确实回复了评论然后删除了该问题,那么鉴于我的声誉低下,我将无法看到它。

标签: python excel pandas dataframe


【解决方案1】:

这可能不是很有效,但如果重复的组具有相同的“顺序”,它就可以工作。

import pandas as pd

df = pd.DataFrame({'id': ['A', 'A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C', 'D', 'D', 'D'],
                   'value1': ['1', '2', '3', '4', '1', '2', '1', '2', '3', '4', '1', '2', '3'],
                   'value2': ['1', '2', '3', '4', '1', '2', '1', '2', '3', '4', '1', '2', '3'],
                   'value3': ['1', '2', '3', '4', '1', '2', '1', '2', '3', '4', '1', '2', '3'],
                   'duplicated': [False] * 13
                   })


def check_dup(df, col1, col2):
    # Checks if two groups are duplicates.
    # First checks the sizes, if they are equal then checks actual values.

    df1 = df[df['id'] == col1][['value1', 'value2', 'value3']]
    df2 = df[df['id'] == col2][['value1', 'value2', 'value3']]
    if df1.size != df2.size:
        return False
    return (df1.values == df2.values).all()


id_unique = set(df['id'].values)  # set of unique ids
id_dic = dict.fromkeys(id_unique, False)  # dict for "duplicated" value for each id
for id1 in id_unique:
    for id2 in id_unique - {id1}:
        if check_dup(df, id1, id2):
            id_dic[id1] = True
            break

# Update 'duplicated' column on df
for id_ in id_dic:
    df.loc[df['id'] == id_, 'duplicated'] = id_dic[id_]

print(df)
   id value1 value2 value3  duplicated
0   A      1      1      1        True
1   A      2      2      2        True
2   A      3      3      3        True
3   A      4      4      4        True
4   B      1      1      1       False
5   B      2      2      2       False
6   C      1      1      1        True
7   C      2      2      2        True
8   C      3      3      3        True
9   C      4      4      4        True
10  D      1      1      1       False
11  D      2      2      2       False
12  D      3      3      3       False

【讨论】:

    【解决方案2】:

    你可以这样做

    首先 sort_values 以防万一,set_index id 和 stack 更改数据的形状并获得带有 to_frame 的单列

    df_ = (df.sort_values(by=["value1","value2","value3"])
             .set_index('id')[["value1","value2","value3"]]
             .stack()
             .to_frame()
          )
    

    其次,您可以为每个 id 附加一个 set_index 和一个 cumcount,使用原始列的名称(Value1 ...)删除索引级别,unstack 以获得每个 id 一行,@ 987654328@ 具有随机值并使用duplicated

    s_dup = df_.set_index([df_.groupby('id').cumcount()], append=True)\
               .reset_index(level=1, drop=True)[0]\
               .unstack()\
               .fillna(0)\
               .duplicated(keep=False)
    print (s_dup)
    id
    A     True
    B    False
    C     True
    D    False
    dtype: bool
    

    现在你可以map 到原始数据框:

    df['dup'] = df['id'].map(s_dup)
    print (df)
       id value1 value2 value3    dup
    0   A      1      1      1   True
    1   A      2      2      2   True
    2   A      3      3      3   True
    3   A      4      4      4   True
    4   B      1      1      1  False
    5   B      2      2      2  False
    6   C      2      2      2   True
    7   C      1      1      1   True
    8   C      3      3      3   True
    9   C      4      4      4   True
    10  D      1      1      1  False
    11  D      2      2      2  False
    12  D      3      3      3  False
    

    【讨论】:

    • 有没有办法设置多个标签,比如“1”、“2”、“3”,来区分不同的重复组?
    猜你喜欢
    • 2013-08-14
    • 2018-04-21
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多