【问题标题】:Compare two columns and remove duplicates on row_pandas比较两列并删除行熊猫中的重复项
【发布时间】:2021-12-09 10:02:38
【问题描述】:

我正在尝试删除列中每一行的重复项,与第二列中的对应行进行比较(相同的 df) 例如,如果列 initial_data 包含存在于 additional_data 中的值,则从 initial_data 行中删除该值并使用该数据创建一个新列。

我的 df

initial_data                                          additional_data
HJC, casco helmets integral de moto                   HJC Helmets
Silverstone Technology  Concentrador de Datos         SilverStone Technology
Urban Leather UR-52 Chaqueta de Cuero                 URBAN 5884

预期输出

new_data
casco integral de moto
Concentrador de Datos 
Leather UR-52 Chaqueta de Cuero


df = [['HJC, casco helmets integral de moto', 'HJC Helmets'], ['Silverstone Technology  Concentrador de Datos ', 'SilverStone Technology'], ['Urban Leather UR-52 Chaqueta de Cuero', 'URBAN 5884']]
df = pd.DataFrame(df, columns = ['initial_data', 'additional_data'])

提一下,我需要保持相同的顺序,相同的大小写,基本上,只是为了删除匹配的单词,而不更改任何其他内容。

非常感谢您分享的任何建议。 我在发布问题之前尝试了多个版本,但没有任何效果(zip、列表等)。

【问题讨论】:

    标签: python pandas duplicates rows


    【解决方案1】:

    这个问题比它最初看起来要复杂一些。一般来说,我认为你需要两个拼图来解决它。首先,您需要一种方法来遍历 pandas DataFrame 中的行并从内容生成一个列值到两列,这就是 apply() 函数很方便的地方。使用参数axis=1 指定您将逐行而不是逐列。

    其次,您需要将字符串分解为标记,以便比较列表。这有时称为文本对齐。在我的示例中,我正在执行单向对齐,检查左列中的任何项是否在右列中不存在,但理论上,右列中也可能存在左列中不存在的项柱子。为了确保单词匹配,我的函数比较所有单词的小写版本并省略任何标点符号,例如您示例中的逗号(尽管您可能想保留它?)。

    import string
    
    mydict = {'initial_data':['HJC, casco helmets integral de moto', 'Silverstone Technology  Concentrador de Datos', 'Urban Leather UR-52 Chaqueta de Cuero'], 
              'additional_data':['HJC Helmets', 'SilverStone Technology', 'URBAN 5884'] }
    df = pd.DataFrame(mydict)
    
    def align_columns(row):
        left = row['initial_data'].split()
        right = row['additional_data'].split()
        
        unmatched = []
        for i in left:
            word = "".join([z for z in i.lower() if z not in string.punctuation])
            if word not in [r.lower() for r in right]:
                unmatched.append(i)
        return " ".join(unmatched)
    df['new_data'] = df.apply(align_columns, axis=1)
    df
    

    【讨论】:

    • 非常感谢,完美!
    【解决方案2】:

    不是一个全面的答案,但有足够的语法让你开始:

    a = df['initial_data'].str.lower().str.split().explode().reset_index()
    b = df['additional_data'].str.lower().str.split().explode().reset_index()
    '''
    [df] a:
    +----+---------+----------------+
    |    |   index | initial_data   |
    |----+---------+----------------|
    |  0 |       0 | hjc            |
    |  1 |       0 | casco          |
    |  2 |       0 | helmets        |
    |  3 |       0 | integral       |
    |  4 |       0 | de             |
    |  5 |       0 | moto           |
    |  6 |       1 | silverstone    |
    |  7 |       1 | technology     |
    |  8 |       1 | concentrador   |
    |  9 |       1 | de             |
    | 10 |       1 | datos          |
    | 11 |       2 | urban          |
    | 12 |       2 | leather        |
    | 13 |       2 | ur-52          |
    | 14 |       2 | chaqueta       |
    | 15 |       2 | de             |
    | 16 |       2 | cuero          |
    +----+---------+----------------+
    '''
    a.columns=['index', 'new_data']
    b.columns=['index', 'new_data']
    
    b = b.loc[b['new_data'].isin(a['new_data'])]
    '''
    [df] b:
    +----+---------+-------------+
    |    |   index | new_data    |
    |----+---------+-------------|
    |  0 |       0 | hjc         |
    |  1 |       0 | helmets     |
    |  2 |       1 | silverstone |
    |  3 |       1 | technology  |
    |  4 |       2 | urban       |
    +----+---------+-------------+    
    '''
    c = pd.concat([a, b], axis=0).drop_duplicates(keep=False) # << KEY IDEA/SYNTAX
    '''
    [df] c:
    +----+---------+--------------+
    |    |   index | new_data     |
    |----+---------+--------------|
    |  1 |       0 | casco        |
    |  3 |       0 | integral     |
    |  4 |       0 | de           |
    |  5 |       0 | moto         |
    |  8 |       1 | concentrador |
    |  9 |       1 | de           |
    | 10 |       1 | datos        |
    | 12 |       2 | leather      |
    | 13 |       2 | ur-52        |
    | 14 |       2 | chaqueta     |
    | 15 |       2 | de           |
    | 16 |       2 | cuero        |
    +----+---------+--------------+   
    ''' 
    c.groupby('index')['new_data'].agg(lambda x: ' '.join(x))
    

    输出:

    index
    0             casco integral de moto
    1              concentrador de datos
    2    leather ur-52 chaqueta de cuero
    Name: new_data, dtype: object
    

    【讨论】:

    • 非常感谢,我已将马特的回答标记为更接近我的用例。也非常感谢您的支持。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    相关资源
    最近更新 更多