非常感谢您阅读。
我有一个大约200,000行和46列的pandas数据框。其中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 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,surname_1和area_1中的组合值与forename_2,surname_2和area_2中所有其他行的组合值进行比较。
我希望使用的测试类型如下:
如果" forename_1 + surname_1 + area_1 + forename_2 + surname_2 + area_2" =" forename_2 + surname_2 + area_2 + forename_1 + surname_1 + area_1", 然后重复删除
我希望只保留x个重复项中的第一个重复行(例如,保持='第一个')。
为了帮助解释,上面有两种情况需要删除副本:
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
george + neil + g + jim + bob + k = george + 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中完成吗?
Compare group of two columns and return index matches R
非常感谢。
答案 0 :(得分:1)
使用:
WeekFields.ISO
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
答案 1 :(得分:1)
我认为使用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')
尽管他们的(forename, surname, area)
三胞胎不同。
为了处理这种可能性,我们可以使用jezrael's original stack/unstack approach,并将df.sort_values
夹在中间:
import numpy as np
import pandas as pd
df = pd.DataFrame(
{'area_1': ['g', 'k', 'k', 'k', 'q', 'w', 's'],
'area_2': ['k', 'g', 'g', 'q', 'k', 'p', 'l'],
'forename_1': ['george', 'george', 'jim', 'pete', 'dan', 'ben', 'charlie'],
'forename_2': ['jim', 'neil', 'george', 'dan', 'pete', 'richard', 'graham'],
'surname_1': ['neil', 'jim', 'bob', 'keith', 'joe', 'steve', 'david'],
'surname_2': ['bob', 'bob', 'neil', 'joe', 'keith', 'ed', 'josh']})
def using_stack_sort_unstack(df):
df = df.copy()
df.columns = df.columns.str.split('_', expand=True)
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()
df2.columns = df2.columns.map('_'.join)
return df2
print(using_stack_sort_unstack(df))
产量
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
stack / sort / unstack操作的目的:
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', 'surname', 'area')
三元组进行排序
个别。排序有助于drop_duplicates
识别(和删除)行
我们想要考虑相同。
这显示了using_stack_sort_unstack
和using_npsort
之间的差异。
请注意using_npsort(df)
返回4行
using_stack_sort_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
答案 2 :(得分:1)
我也有这个问题。我有一个数据帧,其中行可能有两列交换,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_row
...