Python 基于布尔掩码选择行-为什么性能有差异?

Python 基于布尔掩码选择行-为什么性能有差异?,python,pandas,numpy,Python,Pandas,Numpy,我一直在使用pandas DataFrame对象,并根据列值选择行。 我注意到,如果首先使用.values选择行,则速度大约是原来的两倍。为什么会这样? 如果第一个例子比较慢,你有什么理由使用它吗 df = pd.DataFrame(np.random.randint(0, high=10, size=(1000, 4)), columns=['A', 'B', 'C', 'D']) %timeit df_test = df[df['A'] == 9] The slowest run took

我一直在使用pandas DataFrame对象,并根据列值选择行。 我注意到,如果首先使用
.values
选择行,则速度大约是原来的两倍。为什么会这样? 如果第一个例子比较慢,你有什么理由使用它吗

df = pd.DataFrame(np.random.randint(0, high=10, size=(1000, 4)), columns=['A', 'B', 'C', 'D'])

%timeit df_test = df[df['A'] == 9]
The slowest run took 4.98 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 363 µs per loop

%timeit df_test = df[df['A'].values == 9]
1000 loops, best of 3: 181 µs per loop

Pandas masking以序列或数据帧的形式返回布尔掩码。Numpy masking以数组的形式返回布尔掩码

将布尔掩码映射到序列或数据帧比返回布尔数组要花费一些时间

换句话说,将掩码映射到索引并返回一个序列是执行
df['a']==9
或两者相同时的额外时间

举例说明:

df['A'] == 9 

0    False
1    False
2    False
3    False
4    False
Name: A, dtype: bool

type(df['A'] == 9)
pandas.core.series.Series

df['A'].values == 9
array([False, False, False, False, False], dtype=bool)

type(df['A'].values == 9)
numpy.ndarray  
那么为什么numpy掩蔽要快得多的时候还要进行系列掩蔽呢?

假设您有一个以不同方式排序索引的dataframe

df = pd.DataFrame(np.random.randint(0, high=10, size=(5, 4)), columns=list('ABCD'))

   A  B  C  D
0  4  9  1  5
1  8  6  5  0
2  5  5  9  5
3  2  5  7  5
4  1  1  7  2

df2 = pd.DataFrame(np.random.randint(0, high=10, size=(5, 4)), columns=list('ABCD'),index=[4,3,2,1,0])

   A  B  C  D
4  0  4  5  8
3  9  6  7  2
2  0  9  8  6
1  2  6  2  7
0  7  2  8  7
现在,您需要选择
df2
中的行,该行在
df
A
列中有4行,该行基于它们的索引值

# If you do numpy masking 
df2.loc[df['A'].values==4] # First index will be selected no matter what the actual index is 
   A  B  C  D
4  0  4  5  8

df2.loc[df['A']==4] # Row with that index will be selected 
   A  B  C  D
0  7  2  8  7

不仅如此,还有更多的情况需要
索引
数据来处理,因此需要系列屏蔽。希望这能更好地解释问题

好的,这是有道理的。如果第二个场景更快,为什么要在第二个场景中使用第一个场景?我可以告诉你,他们似乎做了完全相同的事情。如果你愿意,你可以使用第二种方法。但在某些情况下,你不只是想要布尔数的简单数组。让我再举一个例子