比较两列并删除 row_pandas 上的重复项

Compare two columns and remove duplicates on row_pandas

我正在尝试删除列中每一行的重复项,与第二列中对应的行进行比较(相同 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、列表等)。

没有太多全面的答案,但足够的语法可以帮助您入门:

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

这个问题比最初看起来要复杂一些。一般来说,我认为你需要两块拼图来解决它。首先,您需要一种方法来遍历 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