2015-05-29 40 views
8

Tôi đang cố gắng đặt một số khác nhau trong một DataFrame gấu trúc tất cả cùng một giá trị. Tôi nghĩ rằng tôi hiểu lập chỉ mục boolean cho gấu trúc, nhưng tôi đã không tìm thấy bất kỳ tài nguyên nào về lỗi cụ thể này.Giá trị cài đặt DataFrame pandas trên mặt nạ boolean

import pandas as pd 
df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']}) 
mask = df.isin([1, 3, 12, 'a']) 
df[mask] = 30 
Traceback (most recent call last): 
... 
TypeError: Cannot do inplace boolean setting on mixed-types with a non np.nan value 

Ở trên, tôi muốn thay thế tất cả các mục True trong mặt nạ có giá trị 30.

Tôi có thể làm df.replace thay vào đó, nhưng mặt nạ cảm thấy hiệu quả hơn và trực quan hơn ở đây. Ai đó có thể giải thích lỗi và cung cấp một cách hiệu quả để đặt tất cả các giá trị không?

+1

Ông có thể xác nhận cho dù câu trả lời của tôi hoặc kết quả Johne được những gì bạn mong muốn và cập nhật câu hỏi của bạn để chỉ rõ điều này, nhờ – EdChum

+0

Cảm ơn , @EdChum. Tôi muốn đặt các giá trị 'True' trong mặt nạ và để các giá trị' False' giống nhau. Tôi đã chỉnh sửa câu hỏi cho rõ ràng. –

+0

Đừng lo, tôi đã cập nhật câu trả lời, bạn chỉ cần đảo ngược mặt nạ để đạt được những gì bạn muốn – EdChum

Trả lời

9

Bạn không thể sử dụng mặt nạ boolean trên dtypes hỗn hợp cho điều này thật không may, bạn có thể sử dụng gấu trúc where để thiết lập các giá trị:

In [59]: 
df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']}) 
mask = df.isin([1, 3, 12, 'a']) 
df = df.where(mask, other=30) 
df 

Out[59]: 
    A B 
0 1 a 
1 30 30 
2 3 30 

Lưu ý: rằng ở trên sẽ thất bại nếu bạn làm inplace=True trong where phương pháp, vì vậy df.where(mask, other=30, inplace=True) sẽ nâng cao:

TypeError: Cannot do inplace boolean setting on mixed-types with a non np.nan value

EDIT

.210

OK, sau một chút hiểu lầm bạn vẫn có thể sử dụng where y chỉ đảo ngược mặt nạ:

In [2]:  
df = pd.DataFrame({'A': [1, 2, 3], 'B': ['a', 'b', 'f']}) 
mask = df.isin([1, 3, 12, 'a']) 
df.where(~mask, other=30) 

Out[2]: 
    A B 
0 30 30 
1 2 b 
2 30 f 
+0

Kết quả có đúng không? 30 có nên được điền vào cho giá trị True hoặc False không?Nó trái ngược với những gì tôi nghĩ đã được yêu cầu (mặc dù tôi có thể có nó ngược) và nó có thể dễ dàng đảo ngược bằng cách lấy bổ sung của mặt nạ. – JohnE

+0

@JohnE có điều này là chính xác, tôi chỉ cần kiểm tra lại – EdChum

+0

@JohnE khi bạn sử dụng 'where', mặt nạ sẽ tạo ra các giá trị ban đầu trong đó mặt nạ là' True', giá trị 'khác' sẽ được sử dụng cho mặt nạ 'False', do đó, mặc định cho' other' là 'NaN', do đó, có vẻ khó hiểu nhưng đây là kết quả mong đợi và mong muốn – EdChum

3

Tôi không chắc chắn 100% nhưng tôi nghi ngờ thông báo lỗi liên quan đến thực tế là không có cách xử lý dữ liệu bị thiếu giống nhau trên các loại dtypes khác nhau. Chỉ float có NaN, nhưng các số nguyên có thể được tự động chuyển đổi sang phao nổi, do đó nó không phải là vấn đề ở đó. Nhưng dường như trộn dtypes số và dtypes đối tượng không hoạt động rất dễ dàng ...

Bất kể điều đó, bạn có thể nhận được xung quanh nó khá dễ dàng với np.where:

df[:] = np.where(mask, 30, df) 

    A B 
0 30 30 
1 2 b 
2 30 f 
+0

Cảm ơn, điều này là đúng. –

1

pandas sử dụng NaN để đánh dấu hợp lệ hoặc thiếu dữ liệu và có thể được sử dụng trên các loại, vì DataFrame là loại dữ liệu chuỗi int và chuỗi hỗn hợp, nó sẽ không chấp nhận gán cho một loại duy nhất (trừ NaN) vì điều này sẽ tạo một loại hỗn hợp (int và str) trong B. -giao nhiệm vụ.

Phương thức @JohnE sử dụng np.where tạo DataFrame mới trong đó loại cột B là đối tượng không phải là chuỗi như trong ví dụ ban đầu.

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