2013-04-14 12 views
100

Tôi có một câu hỏi tương đối đơn giản, hôm nay. Tôi có một con gấu trúc Series đối tượng chứa các giá trị boolean. Làm thế nào tôi có thể nhận được một chuỗi chứa NOT hợp lý của mỗi giá trị?Làm thế nào tôi có thể nhận được phần tử NOT hợp lý của một loạt gấu trúc?

Ví dụ, hãy xem xét một loạt chứa:

True 
True 
True 
False 

Loạt Tôi muốn để có được sẽ chứa:

False 
False 
False 
True 

Điều này có vẻ như nó phải là hợp lý đơn giản, nhưng dường như tôi đã đặt nhầm mojo của tôi hôm nay = (

Cảm ơn!

+0

Điều quan trọng là các dữ liệu không chứa 'loại object' cho các câu trả lời dưới đây để làm việc, vì vậy hãy sử dụng: '~ df.astype ('bool')' – LearnOPhile

Trả lời

115

Để đảo ngược một series boolean, use ~s:

In [7]: s = pd.Series([True, True, False, True]) 

In [8]: ~s 
Out[8]: 
0 False 
1 False 
2  True 
3 False 
dtype: bool 

Sử dụng Python2.7, NumPy 1.8.0, Pandas 0.13.1:

In [119]: s = pd.Series([True, True, False, True]*10000) 

In [10]: %timeit np.invert(s) 
10000 loops, best of 3: 91.8 µs per loop 

In [11]: %timeit ~s 
10000 loops, best of 3: 73.5 µs per loop 

In [12]: %timeit (-s) 
10000 loops, best of 3: 73.5 µs per loop 

Tính đến Pandas 0.13.0, Series có lớp con còn của numpy.ndarray; chúng bây giờ là các lớp con của pd.NDFrame. Điều này có thể liên quan đến lý do tại sao np.invert(s) không còn nhanh như ~s hoặc -s.

Lưu ý: timeit kết quả có thể khác nhau tùy thuộc vào nhiều yếu tố bao gồm phần cứng, trình biên dịch, OS, Python, NumPy và các phiên bản Pandas.

+0

Lưu ý đúng. Khác hơn là chậm hơn nhiều, sự khác biệt giữa dấu ngã và '-' là gì? – blz

+0

Wierd, tôi thực sự đã thử nghiệm 'dấu ngã' như được đề cập trong tài liệu, nhưng nó không thực hiện giống như' np.invert': S – root

+0

@blz: Ít nhất trên máy Ubuntu của tôi, chạy NumPy 1.6.2 , hiệu suất của 'np.invert (s)', '~ s' và' -s' đều giống nhau. – unutbu

8

Tôi chỉ cho nó một sh ot:

In [9]: s = Series([True, True, True, False]) 

In [10]: s 
Out[10]: 
0  True 
1  True 
2  True 
3 False 

In [11]: -s 
Out[11]: 
0 False 
1 False 
2 False 
3  True 
+0

Tôi đã thử mọi toán tử khác với '-'! Tôi sẽ ghi nhớ điều này trong lần sau. – blz

4

Bạn cũng có thể sử dụng numpy.invert:

In [1]: import numpy as np 

In [2]: import pandas as pd 

In [3]: s = pd.Series([True, True, False, True]) 

In [4]: np.invert(s) 
Out[4]: 
0 False 
1 False 
2  True 
3 False 

EDIT: Sự khác biệt trong hoạt động xuất hiện trên Ubuntu 12.04, Python 2.7, NumPy 1.7.0 - dường như không tồn tại sử dụng NumPy 1.6 .2 mặc dù:

In [5]: %timeit (-s) 
10000 loops, best of 3: 26.8 us per loop 

In [6]: %timeit np.invert(s) 
100000 loops, best of 3: 7.85 us per loop 

In [7]: %timeit ~s 
10000 loops, best of 3: 27.3 us per loop 
+0

Rất tuyệt! Cảm ơn các tiêu chuẩn! – blz

6

Câu trả lời của @ unutbu là tại chỗ, chỉ muốn thêm cảnh báo rằng mặt nạ của bạn cần phải là dtype bool, không phải 'đối tượng'. Tức là mặt nạ của bạn không thể có bao giờ có bất kỳ mặt nạ nào. Xem here - ngay cả khi mặt nạ của bạn không có nan bây giờ, nó vẫn sẽ là loại 'đối tượng'.

Nghịch đảo của chuỗi 'đối tượng' sẽ không gây ra lỗi, thay vào đó bạn sẽ nhận được mặt nạ rác của các int không hoạt động như bạn mong đợi.

In[1]: df = pd.DataFrame({'A':[True, False, np.nan], 'B':[True, False, True]}) 
In[2]: df.dropna(inplace=True) 
In[3]: df['A'] 
Out[3]: 
0 True 
1 False 
Name: A, dtype object 
In[4]: ~df['A'] 
Out[4]: 
0 -2 
0 -1 
Name: A, dtype object 

Sau khi nói chuyện với các đồng nghiệp về việc này tôi có một lời giải thích: Có vẻ như gấu trúc đang quay trở lại các nhà điều hành Bitwise:

In [1]: ~True 
Out[1]: -2