熊猫:删除以任何顺序存在的重复项

时间:2018-07-30 23:25:03

标签: python pandas

我的问题类似于Pandas: remove reverse duplicates from dataframe,但我还有其他要求。我需要维护行值对。

例如:

我有data,其中列A对应于列C,列B对应于列D

import pandas as pd

# Initial data frame
data = pd.DataFrame({'A': [0, 10, 11, 21, 22, 35, 5, 50], 
                     'B': [50, 22, 35, 5, 10, 11, 21, 0],
                     'C': ["a", "b", "r", "x", "c", "w", "z", "y"],
                     'D': ["y", "c", "w", "z", "b", "r", "x", "a"]})
data

#    A   B  C  D
#0   0  50  a  y
#1  10  22  b  c
#2  11  35  r  w
#3  21   5  x  z
#4  22  10  c  b
#5  35  11  w  r
#6   5  21  z  x
#7  50   0  y  a

我想删除列AB中存在的重复项,但是我需要在列CD中保留其对应的字母值。

我在这里有一个解决方案,但是有更优雅的方法吗?

# Desired data frame
new_data = pd.DataFrame()

# Concat numbers and corresponding letters
new_data['AC'] = data['A'].astype(str) + ',' + data['C']
new_data['BD'] = data['B'].astype(str) + ',' + data['D']

# Drop duplicates despite order
new_data = new_data.apply(lambda r: sorted(r), axis = 1).drop_duplicates()

# Recreate dataframe
new_data = pd.DataFrame.from_items(zip(new_data.index, new_data.values)).T
new_data = pd.concat([new_data.iloc[:,0].str.split(',', expand=True),
                      new_data.iloc[:,1].str.split(',', expand=True)], axis=1)
new_data.columns=['A', 'B', 'C', 'D']
new_data

#    A  B   C  D
#0   0  a  50  y
#1  10  b  22  c
#2  11  r  35  w
#3  21  x   5  z

编辑技术上的输出应如下所示:

new_data.columns=['A', 'C', 'B', 'D']
new_data

#    A  B   C  D
#0   0  a  50  y
#1  10  b  22  c
#2  11  r  35  w
#3  21  x   5  z

3 个答案:

答案 0 :(得分:3)

我认为您可以使用stackdrop_duplicatesunstack来做到这一点:

data.set_index(['A','B']).stack().drop_duplicates().unstack().reset_index()

    A   B  C  D
0   0  50  a  y
1  10  22  b  c
2  11  35  r  w
3  21   5  x  z

答案 1 :(得分:1)

创建另外两个列,将数据作为列中的排序数据

columns = ['A', 'B']
df = pd.concat([data, pd.DataFrame(np.sort(data[columns], axis=1), axis=1)

使用排序后的数据删除重复项并选择原始列

df.drop_duplicates(df.columns.difference(data.columns))[data.columns]
output:
    A   B  C  D
0   0  50  a  y
1  10  22  b  c
2  11  35  r  w
3  21   5  x  z

答案 2 :(得分:1)

基于您提供的链接

newdf=data[['A','B']].apply(lambda r: sorted(r), axis = 1).drop_duplicates()
newdf['C']=newdf.A.map(dict(zip(data.A,data.C)))
newdf['D']=newdf.B.map(dict(zip(data.B,data.D)))
newdf
Out[138]: 
    A   B  C  D
0   0  50  a  y
1  10  22  b  c
2  11  35  r  w
3   5  21  z  x