2016-11-07 10 views
6

私はABという2つの列を持つデータフレームを持っています。この文脈ではABの順番は重要ではありません。たとえば、私は(0,50)(50,0)を重複していると考えます。パンダでは、これらの複製をデータフレームから削除する効率的な方法は何ですか?パンダ:データフレームから逆の重複を削除

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]}) 
data 
    A B 
0 0 50 
1 10 22 
2 11 35 
3 21 5 
4 22 10 
5 35 11 
6 5 21 
7 50 0 

# Desired output with "duplicates" removed. 
data2 = pd.DataFrame({'A': [0, 5, 10, 11], 
         'B': [50, 21, 22, 35]}) 
data2 
    A B 
0 0 50 
1 5 21 
2 10 22 
3 11 35 

理想的には、出力は列Aの値でソートされます。

答えて

9

あなたは重複をドロップする前に、データフレームの各列を並べ替えることができます。

data.apply(lambda r: sorted(r), axis = 1).drop_duplicates() 

# A B 
#0 0 50 
#1 10 22 
#2 11 35 
#3 5 21 

あなたが列Aによってソートされるように結果を希望する場合:ここで

data.apply(lambda r: sorted(r), axis = 1).drop_duplicates().sort_values('A') 

# A B 
#0 0 50 
#3 5 21 
#1 10 22 
#2 11 35 
+3

ラムダを必要とせず、 '.apply(sorted、axis = 1)'が動作します。 – root

+0

@root。そのとおり。より良い選択肢。 – Psidom

+0

私はこの答えが大好きです!私が思ったことはすべて、データフレームに積み重ねることでした。この巧みさは、その必要性を排除します。 – piRSquared

4

少し醜いですが、より高速なソリューション:

In [44]: pd.DataFrame(np.sort(data.values, axis=1), columns=data.columns).drop_duplicates() 
Out[44]: 
    A B 
0 0 50 
1 10 22 
2 11 35 
3 5 21 

タイミング:8K行のDF

In [50]: big = pd.concat([data] * 10**3, ignore_index=True) 

In [51]: big.shape 
Out[51]: (8000, 2) 

In [52]: %timeit big.apply(lambda r: sorted(r), axis = 1).drop_duplicates() 
1 loop, best of 3: 3.04 s per loop 

In [53]: %timeit pd.DataFrame(np.sort(big.values, axis=1), columns=big.columns).drop_duplicates() 
100 loops, best of 3: 3.96 ms per loop 

In [59]: %timeit big.apply(np.sort, axis = 1).drop_duplicates() 
1 loop, best of 3: 2.69 s per loop 
+1

これは、ベクトル化された実装では同じ答えです。ない!醜い:-) – piRSquared

関連する問題