ฉันจะรับตรรกะที่ไม่ได้เป็นองค์ประกอบของซีรี่ส์หมีแพนด้าได้อย่างไร


229

ฉันมีSeriesวัตถุหมีแพนด้าที่มีค่าบูลีน ฉันจะหาชุดที่มีค่าตรรกะNOTของแต่ละค่าได้อย่างไร

ตัวอย่างเช่นพิจารณาชุดที่มี:

True
True
True
False

ชุดที่ฉันต้องการได้รับประกอบด้วย:

False
False
False
True

ดูเหมือนว่ามันควรจะง่ายพอสมควร แต่ดูเหมือนฉันจะใส่ Mojo ผิด =


1
เป็นสิ่งสำคัญที่ข้อมูลไม่ได้มีobjectประเภทสำหรับคำตอบด้านล่างเพื่อใช้งาน:~ df.astype('bool')
LearnOPhile

ฉันเขียนเกี่ยวกับตัวดำเนินการเชิงตรรกะทั้งหมดในโพสต์นี้ โพสต์ยังมีทางเลือก
cs95

คำตอบ:


260

ในการสลับกลับบูลีนซีรีส์ให้ใช้~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

ใช้ 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

ตั้งแต่ Pandas 0.13.0 ซีรี่ย์ไม่เป็นคลาสย่อยอีกต่อไปของnumpy.ndarray; pd.NDFrameตอนนี้พวกเขาคลาสย่อย นี้อาจมีสิ่งที่จะทำอย่างไรกับเหตุผลที่np.invert(s)จะไม่เป็นอย่างรวดเร็วหรือ~s-s

ข้อแม้: timeitผลลัพธ์อาจแตกต่างกันไปขึ้นอยู่กับปัจจัยหลายประการรวมถึงรุ่นของฮาร์ดแวร์คอมไพเลอร์ OS, Python, NumPy และ Pandas


บันทึกรับรองสำเนาถูกต้อง. นอกเหนือจากการช้าลงมากอะไรคือความแตกต่างระหว่างตัวหนอนและ-?
blz

Wierd ฉันทดสอบจริง ๆtildeตามที่กล่าวไว้ในเอกสาร แต่ไม่ได้ทำงานเหมือนกับnp.invert: S
root

@blz: อย่างน้อยในเครื่องอูบุนตูของฉันทำงาน NumPy 1.6.2 ประสิทธิภาพการทำงานของnp.invert(s), ~sและ-sมีทั้งหมดเดียวกัน
unutbu

@ รูท: ฉันไม่แน่ใจว่าทำไมมีความแตกต่างที่ดีในผลลัพธ์ timeit ของเรา แต่มันสามารถเกิดขึ้นได้อย่างแน่นอน คุณใช้ระบบปฏิบัติการรุ่นใดของ NumPy
unutbu

นอกจากนี้บน Ubuntu แต่ใช้ NumPy 1.7.0 ... ( np.bitwise_not(s)ทำงานเหมือนกับnp.inverse)
ราก

32

คำตอบของ @ unutbu เป็นเพียงแค่ต้องการเพิ่มคำเตือนว่าหน้ากากของคุณจะต้องเป็น dtype บูลไม่ใช่ 'วัตถุ' เช่นหน้ากากของคุณไม่สามารถได้เคยมีใด ๆ ของจังหวัดน่าน ดูที่นี่ - แม้ว่าหน้ากากของคุณจะปราศจากสิ่งสกปรกในขณะนี้มันจะยังคงอยู่ในประเภท 'วัตถุ'

การผกผันของซีรีส์ 'วัตถุ' จะไม่เกิดข้อผิดพลาด แต่คุณจะได้รับมาสก์ขยะที่ไม่ทำงานตามที่คุณคาดหวัง

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

หลังจากพูดคุยกับเพื่อนร่วมงานเกี่ยวกับสิ่งนี้ฉันมีคำอธิบาย: ดูเหมือนว่าหมีแพนด้ากำลังกลับไปที่ผู้ปฏิบัติงานระดับบิต:

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

ตามที่ @geher บอกว่าคุณสามารถแปลงมันเป็นบูลด้วย astype ก่อนที่คุณจะผกผันด้วย ~

~df['A'].astype(bool)
0    False
1     True
Name: A, dtype: bool
(~df['A']).astype(bool)
0    True
1    True
Name: A, dtype: bool

ในตัวอย่างของคุณ, เอาต์พุต ints mask สามารถแปลงเป็นชุดบูลที่คุณต้องการ.astype(bool)เช่น~df['A'].astype(bool)
geher

สิ่งนี้ใช้ได้เพราะastype(bool)เกิดขึ้นก่อน~ ~df['A'].astype(bool)vs(~df['A']).astype(bool)
JSharm

16

ฉันแค่ให้มันยิง:

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

ฉันลองใช้ตัวดำเนินการทุกตัวนอกเหนือจากตัวอักษร-! ฉันจะเก็บเรื่องนี้ไว้ในใจครั้งต่อไป
blz

6

คุณยังสามารถใช้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

แก้ไข: ความแตกต่างของประสิทธิภาพปรากฏบน Ubuntu 12.04, Python 2.7, NumPy 1.7.0 - ดูเหมือนไม่มีอยู่โดยใช้ NumPy 1.6.2 ว่า:

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

อาจไม่ถูกต้องบนแพลตฟอร์มอื่น Win 7, python 3.6.3 numpy 1.13.3, pandas 0.20.3, (-s) จะเร็วที่สุด (~ s) คือวินาทีและ np.invert (s) ช้าที่สุด
gaozhidf

0

NumPy ช้าลงเพราะมันส่งสัญญาณอินพุตไปยังค่าบูลีน (ดังนั้นไม่มีและ 0 กลายเป็นเท็จและทุกอย่างอื่นกลายเป็นจริง)

import pandas as pd
import numpy as np
s = pd.Series([True, None, False, True])
np.logical_not(s)

ให้คุณ

0    False
1     True
2     True
3    False
dtype: object

ในขณะที่ ~ s จะผิดพลาด ในกรณีส่วนใหญ่ตัวหนอนจะเป็นตัวเลือกที่ปลอดภัยกว่า NumPy

นุ่น 0.25, NumPy 1.17

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.