2017-09-04 53 views
2

非常感謝您的閱讀。刪除列值已交換的重複行

我有一個大約200,000行和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  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 

喬治+尼爾+ G +吉姆+擺錘+ K =喬治+尼爾+ G +吉姆+鮑勃+ ķ等等

在每種情況下,兩個第二排將被刪除,這意味着我的預期產出將是:

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 2與此交易的答案,但那裏還有一種方式是可以在Python中完成的嗎?

Compare group of two columns and return index matches R

非常感謝。

回答

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 

堆棧的目的/排序/拆散操作:

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_unstackusing_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 
+0

非常感謝您的回答,我確實在考慮排序問題以前的答案會擺脫一些沒有重複的對,我會盡快測試這個更新的答案,並讓你知道它是否成功,謝謝! – Charlie0210

+0

當這個方法也有整數值的列時, t似乎我可能不得不將它們轉換爲字符串,然後再進行排序?非常感謝您的幫助 – Charlie0210

+1

上述方法應該可以在數值列值AFAICS下正常工作。但是如果你可以發佈一個演示這個問題的例子,我們會看看它。 – unutbu

1

用途:

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 

print (pd.DataFrame(np.sort(df.values, axis=1), index=df.index)) 
     0  1  2  3  4  5 
0  bob  g george  jim  k neil 
1  bob  g george  jim  k neil 
2  dan  joe  k keith pete  q 
3  dan  joe  k keith pete  q 
4  ben  ed  p richard steve  w 
5 charlie david graham  josh  l  s 
6  bob charlie david  jim  k  s 

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 
6  bob charlie david  jim  k  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 
6 charlie  david  s  jim  bob  k 
+0

感謝您的答覆jezrael。我想保留每行上的名字對。我認爲如果這兩個組合(_1和_2)被堆疊和堆疊,那麼這導致一些對丟失。 – Charlie0210

+0

是的,笨蛋會丟失。他們被Nones取代。在輸出中創建3列數據幀不是更好嗎? (只是想法) – jezrael

+0

在上面的例子中,你添加了第五行的行值「charlie,david,s,jim bob,k。我不想丟失這行,因爲數據集中不存在第二行列的值爲: – Charlie0210