2017-08-27 37 views
5

Xem xét dataframe sauLàm thế nào để có điều kiện loại bỏ bản sao từ một dataframe gấu trúc

import pandas as pd 
df = pd.DataFrame({'A' : [1, 2, 3, 3, 4, 4, 5, 6, 7], 
        'B' : ['a','b','c','c','d','d','e','f','g'], 
        'Col_1' :[np.NaN, 'A','A', np.NaN, 'B', np.NaN, 'B', np.NaN, np.NaN], 
        'Col_2' :[2,2,3,3,3,3,4,4,5]}) 
df 
Out[92]: 
    A B Col_1 Col_2 
0 1 a NaN  2 
1 2 b  A  2 
2 3 c  A  3 
3 3 c NaN  3 
4 4 d  B  3 
5 4 d NaN  3 
6 5 e  B  4 
7 6 f NaN  4 
8 7 g NaN  5 

Tôi muốn loại bỏ tất cả các hàng mà là bản sao liên quan đến cột 'A' 'B'. Tôi muốn xóa mục nhập có mục nhập NaN (Tôi biết rằng đối với tất cả các chế độ sẽ có một số NaN và mục nhập không phải là NaN). Kết quả cuối cùng sẽ giống như thế này

A B Col_1 Col_2 
0 1 a NaN  2 
1 2 b  A  2 
2 3 c  A  3 
4 4 d  B  3 
6 5 e  B  4 
7 6 f NaN  4 
8 7 g NaN  5 

Tất cả hiệu quả, một lớp lót được hoan nghênh nhất

+0

Để bảo vệ cử tri xuống, bạn có thể đã chọn ví dụ đơn giản là 'df.drop_duplicates' cho bạn câu trả lời bạn không muốn. –

+0

có. Tôi chấp nhận downvote :) – mortysporty

Trả lời

3

Dưới đây là một sự thay thế:

df[~((df[['A', 'B']].duplicated(keep=False)) & (df.isnull().any(axis=1)))] 
# A B Col_1 Col_2 
# 0 1 a NaN  2 
# 1 2 b  A  2 
# 2 3 c  A  3 
# 4 4 d  B  3 
# 6 5 e  B  4 
# 7 6 f NaN  4 
# 8 7 g NaN  5 

này sử dụng các phép toán "không phải là" nhà điều hành ~ phủ nhận hàng đáp ứng các điều kiện chung trở thành một hàng trùng lặp (đối số keep=False khiến phương thức đánh giá thành True cho tất cả các hàng không phải duy nhất) và chứa ít nhất một giá trị null. Vì vậy, nơi biểu thức df[['A', 'B']].duplicated(keep=False) lợi nhuận loạt tài liệu này:

# 0 False 
# 1 False 
# 2  True 
# 3  True 
# 4  True 
# 5  True 
# 6 False 
# 7 False 
# 8 False 

... và các biểu hiện df.isnull().any(axis=1) lợi nhuận loạt tài liệu này:

# 0  True 
# 1 False 
# 2 False 
# 3  True 
# 4 False 
# 5  True 
# 6 False 
# 7  True 
# 8  True 

... chúng tôi quấn cả trong ngoặc đơn (theo yêu cầu của cú pháp Pandas bất cứ khi nào sử dụng nhiều biểu thức trong hoạt động lập chỉ mục) và sau đó quấn chúng trong ngoặc đơn lại để chúng tôi có thể phủ nhận toàn bộ biểu thức (ví dụ: ~(...)), như sau:

~((df[['A','B']].duplicated(keep=False)) & (df.isnull().any(axis=1))) & (df['Col_2'] != 5) 

# 0  True 
# 1  True 
# 2  True 
# 3 False 
# 4  True 
# 5 False 
# 6  True 
# 7  True 
# 8 False 

Bạn có thể tạo các điều kiện phức tạp hơn với việc sử dụng thêm các toán tử logic &| (toán tử "hoặc"). Giống như với SQL, nhóm các điều kiện của bạn khi cần thiết với các dấu ngoặc đơn bổ sung; ví dụ: bộ lọc dựa trên logic "cả hai điều kiện X AND Y là đúng hoặc điều kiện Z là đúng" với df[ ((X) & (Y)) | (Z) ].

+0

Tôi nghĩ bạn cần phải chuyển 'keep = False' thành' duplicateated' để làm việc này. – ayhan

+0

@ayhan Tôi chỉ đang nghĩ như vậy :) – cmaher

+0

Xin chào. Liệu điều này có hiệu quả nếu có một số giá trị khác hơn 'NaN' mà chúng ta muốn loại bỏ? Chúng ta có thể sửa đối số sau '&' không? – mortysporty

5

Nếu mục tiêu là để chỉ thả NaN bản sao, một giải pháp nhẹ tham gia nhiều hơn là cần thiết.

Trước tiên, hãy phân loại trên A, BCol_1, vì vậy NaN s được chuyển xuống cuối mỗi nhóm. Sau đó gọi df.drop_duplicates với keep=first:

out = df.sort_values(['A', 'B', 'Col_1']).drop_duplicates(['A', 'B'], keep='first') 
print(out) 

    A B Col_1 Col_2 
0 1 a NaN  2 
1 2 b  A  2 
2 3 c  A  3 
4 4 d  B  3 
6 5 e  B  4 
7 6 f NaN  4 
8 7 g NaN  5 
+0

Có lẽ :) nhưng điều này đảm bảo rằng các giá trị 'NaN' không 'Col_1' là các hàng được lưu giữ không? – mortysporty

+1

@mortysporty Đã chỉnh sửa. –

+0

Tôi đã nhận được cả một downvote và và upvote về bài đăng này.Tôi đoán rằng tôi xứng đáng được nhận thấy rằng câu trả lời dễ dàng như thế nào. Nhưng bạn giải quyết nó nhanh hơn rất nhiều so với tôi sẽ có :) cảm ơn! – mortysporty

1

Hoặc bạn chỉ có thể sử dụng first(), bằng cách sử dụng đầu tiên, sẽ trả lại giá trị notnull đầu tiên, do đó thứ tự của mục nhập ban đầu không thực sự quan trọng.

df.groupby(['A','B']).first() 

Out[180]: 
    Col_1 Col_2 
A B    
1 a NaN  2 
2 b  A  2 
3 c  A  3 
4 d  B  3 
5 e  B  4 
6 f NaN  4 
7 g NaN  5 
Các vấn đề liên quan