微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python-基于布尔掩码选择行-为什么性能有所不同?

我一直在使用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

解决方法:

熊猫遮罩以系列或DataFrame的形式返回布尔型遮罩. 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屏蔽时,系列屏蔽会更快呢?

假设您的数据框的索引以不同的方式排序

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

不仅如此,在更多情况下,您还希望索引和列数据可以使用,因此需要进行系列屏蔽.希望能更好地解释.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐