Python 删除已交换列值的重复行
非常感谢你的阅读 我有一个大约200000行46列的熊猫数据框。其中23列以“_1”结尾,另23列以“_2”结尾。例如:Python 删除已交换列值的重复行,python,pandas,dataframe,duplicates,Python,Pandas,Dataframe,Duplicates,非常感谢你的阅读 我有一个大约200000行46列的熊猫数据框。其中23列以“_1”结尾,另23列以“_2”结尾。例如: forename_1 surname_1 area_1 forename_2 surname_2 area_2 george neil g jim bob k jim bob k george neil
forename_1 surname_1 area_1 forename_2 surname_2 area_2
george neil g jim bob k
jim bob k george neil g
pete keith k dan joe q
dan joe q pete keith k
ben steve w richard ed p
charlie david s graham josh l
我已经使用drop_duplicates成功地删除了重复项,但是现在我想删除重复的行,但是它们所在的组(1或2)已反转
也就是说,对于一行,我想将forename_1、Lastname_1和area_1中的组合值与所有其他行的forename_2、Lastname_2和area_2中的组合值进行比较
我希望使用的测试类型如下:
如果“名字\ 1+姓氏\ 1+区域\ 1+名字\ 2+姓氏\ 2+区域\ 2”=“名字\ 2+姓氏\ 2+区域\ 2+名字\ 1+姓氏\ 1+区域\ 1”,
然后进行重复数据消除
我只想保留x个重复行中的第一个重复行(例如keep='first')
为了帮助解释,上面有两种情况需要删除副本:
forename_1 surname_1 area_1 forename_2 surname_2 area_2
george neil g jim bob k
jim bob k george neil g
forename_1 surname_1 area_1 forename_2 surname_2 area_2
pete keith k dan joe q
dan joe q pete keith k
乔治+neil+g+jim+bob+k=乔治+neil+g+jim+bob+k等等
在每种情况下,这两行中的第二行将被删除,这意味着我的预期输出将是:
forename_1 surname_1 area_1 forename_2 surname_2 area_2
george neil g jim bob k
pete keith k dan joe q
ben steve w richard ed p
charlie david s graham josh l
我已经看到了一个在R中处理这个问题的答案,但是还有一种方法可以在Python中实现吗
非常感谢。使用:
df1 = pd.DataFrame(np.sort(df.values, axis=1), index=df.index).drop_duplicates()
print (df1)
0 1 2 3 4 5
0 bob g george jim k neil
2 dan joe k keith pete q
4 ben ed p richard steve w
5 charlie david graham josh l s
df2 = df.loc[df1.index]
print (df2)
forename_1 surname_1 area_1 forename_2 surname_2 area_2
0 george neil g jim bob k
2 pete keith k dan joe q
4 ben steve w richard ed p
5 charlie david s graham josh l
我认为使用
np.sort(df.values,axis=1)
有问题。虽然它独立地对每一行进行排序(好),但它不考虑值来自哪一列(坏)。换句话说,这两个假设行
forename_1 surname_1 area_1 forename_2 surname_2 area_2
george neil g jim bob k
george jim k neil bob g
将得到相同的排序
In [377]: np.sort(np.array([['george', 'neil', 'g', 'jim', 'bob', 'k'],
['george', 'jim', 'k', 'neil', 'bob', 'g']]), axis=1)
.....: Out[377]:
array([['bob', 'g', 'george', 'jim', 'k', 'neil'],
['bob', 'g', 'george', 'jim', 'k', 'neil']],
dtype='<U6')
屈服
area_1 area_2 forename_1 forename_2 surname_1 surname_2
0 g k george jim neil bob
1 k g george neil jim bob
3 q k dan pete joe keith
5 w p ben richard steve ed
6 s l charlie graham david josh
堆栈/排序/取消堆栈操作的目的:
df2 = df.stack()
df2 = df2.sort_values(by=['forename', 'surname', 'area'])
colnum = (df2.groupby(level=0).cumcount()+1).astype(str)
df2.index = pd.MultiIndex.from_arrays([df2.index.get_level_values(0), colnum])
df2 = df2.unstack().drop_duplicates()
是对每行中的('forename'、'names'、'area')
三元组进行排序
个别地。排序有助于删除\u重复项
识别(并删除)行
我们想考虑相同的。< /P>
这显示了
使用\u stack\u sort\u unstack
和使用\u nport
之间的区别。
请注意,使用\u nport(df)
在
使用\u stack\u sort\u unstack(df)
返回5行:
def using_npsort(df):
df1 = pd.DataFrame(np.sort(df.values, axis=1), index=df.index).drop_duplicates()
df2 = df.loc[df1.index]
return df2
print(using_npsort(df))
# area_1 area_2 forename_1 forename_2 surname_1 surname_2
# 0 g k george jim neil bob
# 3 k q pete dan keith joe
# 5 w p ben richard steve ed
# 6 s l charlie graham david josh
我也有这个问题。我有一个数据框,其中行可以交换两列,
Sample1
&Sample2
。我的例子可能更可靠一些,但我想确定一下
data = pd.DataFrame({ 'Sample1': [ 'AT1', 'AT1', 'AT1', 'AT1', 'AT2', 'AT2', 'AT2', 'AT2', 'AT3', 'AT3', 'AT3', 'AT3', 'AT4', 'AT4', 'AT4', 'AT4', 'AT5', 'AT5', 'AT5', 'AT5'], 'Sample2': [ 'AT2', 'AT3', 'AT4', 'AT5', 'AT1', 'AT3', 'AT4', 'AT5', 'AT1', 'AT2', 'AT4', 'AT5', 'AT1', 'AT2', 'AT3', 'AT5', 'AT1', 'AT2', 'AT3', 'AT4'], 's1v': [ 53, 69, 44, 54, 27, 60, 11, 98, 16, 48, 50, 68, 89, 9, 20, 0, 14, 42, 1, 85], 's2v': [ 27, 16, 89, 14, 53, 48, 9, 42, 69, 60, 20, 1, 44, 11, 50, 85, 54, 98, 68, 0], 'v': [ 74, 0, 36, 87, 74, 87, 64, 64, 0, 87, 2, 54, 36, 64, 2, 51, 87, 64, 54, 51] })
# Add duplicate marker column
data['duplicate'] = False
# Scan table for duplicate rows
for index, row in data.iterrows():
s1 = row['Sample1']
s2 = row['Sample2']
data_row = data.iloc[ index ]
if data_row['duplicate'] == False:
dup_row = data.loc[ (data['Sample1'] == s2) & (data['Sample2'] == s1) ]
if not dup_row.empty:
data.loc[ (data['Sample1'] == s2) & (data['Sample2'] == s1), 'duplicate' ] = True
# Subset data
data = data.loc[ data['duplicate'] == False ]
我无法使用
iterrows()
中的行,因为它在数据框中不包含更新的值,这就是为什么我有data\u行
…感谢您的回复。我想把每一行的两个名字放在一起。我认为如果这两个组(_1和_2)是堆叠和未堆叠的,那么这将导致一些对丢失。是的,重复将丢失。他们被无名小卒所取代。在输出中创建3列数据帧不是更好吗?(仅限想法)在上面的示例中,您添加了第五行,其中包含行值“查理,大卫,s,吉姆,鲍勃,k。我不想丢失这一行,因为数据集中不存在第二行的列值为jim、bob、k、charlie、david、s。我添加了另一个解决方案—它对每行的所有值进行排序并删除重复项。然后按loc仅选择索引与重复数据消除df相同的所有行。非常感谢您的帮助,我将在我的数据样本上测试这一点并检查结果非常感谢您的回答,我确实想知道上一个回答中的排序是否会消除一些不重复的对。我将很快测试这个更新的答案,并让你知道它是否成功,谢谢!当还有整数值的列时,此方法是否有效?似乎我必须在排序之前将这些转换为字符串?再次非常感谢您的帮助上述方法应该可以很好地处理数值列值AFAICS。但是如果你能发布一个例子来说明这个问题,我们会看一看。
def using_npsort(df):
df1 = pd.DataFrame(np.sort(df.values, axis=1), index=df.index).drop_duplicates()
df2 = df.loc[df1.index]
return df2
print(using_npsort(df))
# area_1 area_2 forename_1 forename_2 surname_1 surname_2
# 0 g k george jim neil bob
# 3 k q pete dan keith joe
# 5 w p ben richard steve ed
# 6 s l charlie graham david josh
data = pd.DataFrame({ 'Sample1': [ 'AT1', 'AT1', 'AT1', 'AT1', 'AT2', 'AT2', 'AT2', 'AT2', 'AT3', 'AT3', 'AT3', 'AT3', 'AT4', 'AT4', 'AT4', 'AT4', 'AT5', 'AT5', 'AT5', 'AT5'], 'Sample2': [ 'AT2', 'AT3', 'AT4', 'AT5', 'AT1', 'AT3', 'AT4', 'AT5', 'AT1', 'AT2', 'AT4', 'AT5', 'AT1', 'AT2', 'AT3', 'AT5', 'AT1', 'AT2', 'AT3', 'AT4'], 's1v': [ 53, 69, 44, 54, 27, 60, 11, 98, 16, 48, 50, 68, 89, 9, 20, 0, 14, 42, 1, 85], 's2v': [ 27, 16, 89, 14, 53, 48, 9, 42, 69, 60, 20, 1, 44, 11, 50, 85, 54, 98, 68, 0], 'v': [ 74, 0, 36, 87, 74, 87, 64, 64, 0, 87, 2, 54, 36, 64, 2, 51, 87, 64, 54, 51] })
# Add duplicate marker column
data['duplicate'] = False
# Scan table for duplicate rows
for index, row in data.iterrows():
s1 = row['Sample1']
s2 = row['Sample2']
data_row = data.iloc[ index ]
if data_row['duplicate'] == False:
dup_row = data.loc[ (data['Sample1'] == s2) & (data['Sample2'] == s1) ]
if not dup_row.empty:
data.loc[ (data['Sample1'] == s2) & (data['Sample2'] == s1), 'duplicate' ] = True
# Subset data
data = data.loc[ data['duplicate'] == False ]