2016-10-06 26 views
6

Tôi có một dataframe đơn giản như vậy:Thay thế các giá trị trùng lặp trên các cột trong Pandas

df = [ {'col1' : 'A', 'col2': 'B', 'col3': 'C', 'col4':'0'}, 
      {'col1' : 'M', 'col2': '0', 'col3': 'M', 'col4':'0'}, 
      {'col1' : 'B', 'col2': 'B', 'col3': '0', 'col4':'B'}, 
      {'col1' : 'X', 'col2': '0', 'col3': 'Y', 'col4':'0'} 
      ] 
df = pd.DataFrame(df) 
df = df[['col1', 'col2', 'col3', 'col4']] 
df 

nào trông như thế này:

| col1 | col2 | col3 | col4 | 
|------|------|------|------| 
| A | B | C | 0 | 
| M | 0 | M | 0 | 
| B | B | 0 | B | 
| X | 0 | Y | 0 | 

Tôi chỉ muốn thay thế ký tự lặp đi lặp lại với nhân vật '0' , trên các hàng. Nó tóm tắt để giữ giá trị trùng lặp đầu tiên mà chúng tôi gặp phải, như sau:

| col1 | col2 | col3 | col4 | 
|------|------|------|------| 
| A | B | C | 0 | 
| M | 0 | 0 | 0 | 
| B | 0 | 0 | 0 | 
| X | 0 | Y | 0 | 

Điều này có vẻ đơn giản nhưng tôi bị kẹt. Bất kỳ nudges đúng hướng sẽ được thực sự đánh giá cao.

Trả lời

7

Bạn có thể sử dụng phương pháp duplicated để trả về một indexer boolean cho dù yếu tố này là bản sao hay không:

In [214]: pd.Series(['M', '0', 'M', '0']).duplicated() 
Out[214]: 
0 False 
1 False 
2  True 
3  True 
dtype: bool 

Sau đó, bạn có thể tạo ra một mặt nạ bằng cách ánh xạ này trên các hàng của dataframe của bạn, và sử dụng where để thực hiện thay thế của bạn:

is_duplicate = df.apply(pd.Series.duplicated, axis=1) 
df.where(~is_duplicate, 0) 

    col1 col2 col3 col4 
0 A B C 0 
1 M 0 0 0 
2 B 0 0 0 
3 X 0 Y 0 
+1

Tuyệt vời - Tôi đã nghĩ đến việc xếp chồng/nhóm/xoay vòng, nhưng điều này là nhiều, sạch hơn nhiều. Bạn có thể tránh lambda bằng cách sử dụng 'pd.Series.duplicated' trực tiếp, nhưng đó là nhỏ. – DSM

+0

@ DSM đó là một mẹo hay, tôi sẽ chỉnh sửa – maxymoo

+0

Các bạn thật tuyệt vời. –

Các vấn đề liên quan