我试图删除一列中每一行的重复项,与第二列中的对应行进行比较(相同的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,列表等)。
这个问题比最初看起来要复杂一些。一般来说,我认为你需要两块拼图来解开它。首先,您需要一种方法来遍历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
不是一个非常全面的答案,但足以让您入门:
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