Pandas交换值(如果在另一列中找到该值)



我有两列,每列都有一个字符串列表,分别命名为Tag 1和Tag 2。简单地说,我需要检查单元格中的字符串是否在相邻列的任何位置找到,如果找到,请交换值。

现有数据帧

Tag 1    Tag 2
Amazon   Twitter
Amazon   Google
eBay     Amazon
Reddit   Facebook

所需输出

Tag 1    Tag 2
Amazon   Twitter
Amazon   Google
Amazon   eBay
Reddit   Facebook

在期望的结果中,你可以看到亚马逊已经与eBay交换了位置,因为它是在标签1列中找到的。

最小再现性示例

import pandas as pd
data = {'Tag 1': ['Amazon', 'Amazon', 'eBay', 'Reddit'],
'Tag 2': ['Twitter', 'Google', 'Amazon', 'Facebook']}
df = pd.DataFrame(data)

我一直在研究类似的帖子,但似乎不能完全正确。

这是我迄今为止的代码。

您可以使用pd.where来检查"Tag 2"中的值何时存在于使用isin的"Tag 1"中,并在分配回时交换值:

df[['Tag 1','Tag 2']] = df[['Tag 2','Tag 1']].where(
df['Tag 2'].isin(df['Tag 1'].tolist()), df[['Tag 1','Tag 2']].values)

打印回:

Tag 1     Tag 2
0  Amazon   Twitter
1  Amazon    Google
2  Amazon      eBay
3  Reddit  Facebook

这可能会实现

import pandas as pd
import numpy as np
data = {'Tag 1': ['Amazon', 'Amazon', 'eBay', 'Reddit'],
'Tag 2': ['Twitter', 'Google', 'Amazon', 'Facebook']}
df = pd.DataFrame(data)
values = np.unique(df['Tag 1'].values)  # All unique values in Tag 1
swapped = []  # So we don't double swap
for val in values:
rows = df.loc[df['Tag 2'] == val]  # Get rows in Tag 2 that matches
for idx, row in rows.iterrows():
if idx in swapped:  # Ignore if already swapped
continue
# Swap the values
temp = df.iloc[idx]['Tag 2']
df.iloc[idx]['Tag 2'] = df.iloc[idx]['Tag 1']
df.iloc[idx]['Tag 1'] = temp
swapped.append(idx)

可能还有更有效的解决方案,但我认为这一点非常清楚。它遍历"标记1"列中的每个唯一值,检查"标记2"列中是否匹配,并交换它们。我不确定你是否想避免双重互换,但如果不是必须的话,可以取消。

@ssophocles的答案可能是正确的。

然而,例如,如果您只想按字典顺序对列进行重新排序,请尝试:

tags = ['Tag 1', 'Tag 2']
df[tags] = df[tags].apply(lambda x: sorted(tuple(x)), axis=1, result_type='expand')
print(df)
# Output
Tag 1    Tag 2
0    Amazon  Twitter
1    Amazon   Google
2    Amazon     eBay
3  Facebook   Reddit

最新更新