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