在使用Numpy时,我经常需要使用布尔索引来访问数组的各个部分。为了使内容更易于阅读和输入,我经常将这些子数组存储到新变量中,例如:
n = 10000
X = np.random.rand((n, n))
W = np.random.random_integers(0, 1, n)
X0 = X[W==0]
X1 = X[W==1]
但是,当我处理越来越大的数据集时,这似乎非常浪费。在这种情况下,建议的做法是什么?我是否应该每次只写(在上面的示例中)X [W == 0]和X [W == 1]?
如果要索引的元素数量有限,则可能需要将索引存储为索引列表。为此,numpy.nonzero
它非常有用。但是,如果要索引的元素数量很大,则通过存储布尔数组(每个元素1个字节)可以使用较少的内存。
因此,有四种可能性:
从内存存储的角度来看,备选方案1每个维度的每个索引元素占用8个字节。(当然,可以通过使用平面索引来避免“按维度”。)布尔方法每个元素占用1个字节,因此,如果True
布尔表中包含a的元素多于1/8 ,则更多节省空间的解决方案。解决方案3可能占用与布尔解决方案相同的空间。
(我对NumPy的内部知识了解不足,无法对屏蔽数组说太多。我怀疑它们的行为类似于布尔索引。)
在性能方面情况类似。如果要选择的元素很多,则布尔型解决方案是有效的,但是如果元素数量很少,则索引解决方案会更好。
只是给出一些基准测试想法:
import numpy as np
import time
def create_indices(prob):
data = np.random.random(100000000) < prob
return data, np.nonzero(data)
def bool_index(data):
return data[data]
def list_index(data, indices):
return data[indices]
通过使用具有不同概率的时间,结果为:
p boolean list
0.01 0.206 0.012
0.10 0.415 0.099
0.20 0.405 0.146
0.50 0.786 0.373
0.75 0.539 0.555
1.00 0.214 0.723
这实际上非常有趣:当元素的一半为时,使用布尔索引最糟糕True
。使用列表索引的行为符合预期。
此基准绝不能视为全部事实。可能是要建立索引的数组的类型改变了情况(此处bool
与相同uint8
),等等。但是,在大多数情况下,性能方面的列表索引似乎非常好。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句