2017-05-10 11 views
3

の列に重複する値を削除します。は、私はパンダのデータフレームを持っているパンダのデータフレーム

>>df_freq = pd.DataFrame([["Z11", "Z11", "X11"], ["Y11","",""], ["Z11","Z11",""]], columns=list('ABC')) 

>>df_freq 
    A B C 
0 Z11 Z11 X11 
1 Y11  
2 Z11 Z11 

私は、各行が唯一の一意の値を持っていることを確認します。したがって、それはこのようになるはずです:削除された値がゼロまたは空

A B C 
0 Z11 0 X11 
1 Y11  
2 Z11 0 

に置き換えることができます私のデータフレームは、行の列と数千人の何百もの大きさです。目標は、そのデータフレームの一意の値を数えることです。私は、マトリックスに変換するデータフレームを用いて

>>np.unique(mat.astype(str), return_counts=True) 

しかし、特定の行(複数可)にを適用することにより、同一の値が発生し、Iはnp.unique()メソッドを適用する前にそれを削除することを行います。私は各行に一意の値を保持したい。

答えて

5

使用astype(bool)の組み合わせと

mask = df_freq.apply(pd.Series.duplicated, 1) & df_freq.astype(bool) 

df_freq.mask(mask, 0) 

    A B C 
0 Z11 0 X11 
1 Y11   
2 Z11 0  
+0

現場での変更に基づいて変換できますか?それをタイムリーにしたいですか? – Divakar

+0

ちょっとpiR、 'df_freq.astype(bool)'の理由は何ですか?コードはそれなしで正常に動作するようです。 – Moondra

+0

@moondra OPにはデータフレームに空白があり、複数のものがありました。第2、第3などの空白が現れたときにゼロを置くことはしませんでした。だから、 '' 'は' False'と評価されるので、 '' df_freq.astype(bool) 'を使って何も空でないマスクを作成します。重複があるときと一緒に、ゼロを正確に配置することができます。それ以外の場合は、 'df_freq.loc [1、 'C']' – piRSquared

0
def replaceDuplicateData(nestedList): 
    for row in range(len(nestedList)): 
     uniqueDataRow = [] 
     for col in range(len(nestedList[row])): 
      if nestedList[row][col] not in uniqueDataRow: 
       uniqueDataRow.append(nestedList[row][col]) 
      else: 
       nestedList[row][col] = 0 
    return nestedList 

nestedList = [["Z11", "Z11", "X11"], ["Y11","",""], ["Z11","Z11",""]] 
print (replaceDuplicateData(nestedList)) 

duplicatedは基本的に、あなたのマトリックスに重複を削除するには上記のその機能を使用することができます。

1

ここでベクトル化numpyのアプローチだ -

def reset_rowwise_dups(df): 
    n = df.shape[0] 
    row_idx = np.arange(n)[:,None] 

    a = df_freq.values 
    idx = np.argsort(a,1) 
    sorted_a = a[row_idx, idx] 
    idx_reversed = idx.argsort(1) 
    sorted_a_dupmask = sorted_a[:,1:] == sorted_a[:,:-1] 
    dup_mask = np.column_stack((np.zeros(n,dtype=bool), sorted_a_dupmask)) 
    final_mask = dup_mask[row_idx, idx_reversed] & (a != '') 
    a[final_mask] = 0 

サンプル実行 -

In [80]: df_freq 
Out[80]: 
    A B C D 
0 Z11 Z11 X11 Z11 
1 Y11   Y11 
2 Z11 Z11  X11 

In [81]: reset_rowwise_dups(df_freq) 

In [82]: df_freq 
Out[82]: 
    A B C D 
0 Z11 0 X11 0 
1 Y11   0 
2 Z11 0  X11 

ランタイムテスト

# Proposed earlier in this post 
def reset_rowwise_dups(df): 
    n = df.shape[0] 
    row_idx = np.arange(n)[:,None] 

    a = df.values 
    idx = np.argsort(a,1) 
    sorted_a = a[row_idx, idx] 
    idx_reversed = idx.argsort(1) 
    sorted_a_dupmask = sorted_a[:,1:] == sorted_a[:,:-1] 
    dup_mask = np.column_stack((np.zeros(n,dtype=bool), sorted_a_dupmask)) 
    final_mask = dup_mask[row_idx, idx_reversed] & (a != '') 
    a[final_mask] = 0 

# @piRSquared's soln using pandas apply 
def apply_based(df): 
    mask = df.apply(pd.Series.duplicated, 1) & df.astype(bool) 
    return df.mask(mask, 0) 

タイミング -

In [151]: df_freq = pd.DataFrame([["Z11", "Z11", "X11", "Z11"], \ 
    ...: ["Y11","","", "Y11"],["Z11","Z11","","X11"]], columns=list('ABCD')) 

In [152]: df_freq 
Out[152]: 
    A B C D 
0 Z11 Z11 X11 Z11 
1 Y11   Y11 
2 Z11 Z11  X11 

In [153]: df = pd.concat([df_freq]*10000,axis=0) 

In [154]: df.index = range(df.shape[0]) 

In [155]: %timeit apply_based(df) 
1 loops, best of 3: 3.35 s per loop 

In [156]: %timeit reset_rowwise_dups(df) 
100 loops, best of 3: 12.7 ms per loop 
+0

で余分な '0'をキャッチしませんでした。申し訳ありませんでした:-) – piRSquared

関連する問題