假设我有一个非常大的np.array
有N个元素,我想只选择一些通过S选择的值。通常的方法是:
selected_items = original_array[selection1(original_array) & original_array > 3]
这很好但是使用了很多临时内存。如果我是正确的,我需要S大小为N的布尔值,加上&
结果的至少另一个。在内存使用方面是否有更好的解决方案?例如,显式循环不需要:
selected_items = []
tests = (selection1, lambda x: x > 3)
for x in orignal_items:
if all( (t(x) for t in tests) ):
selected_items.append(x)
我喜欢numpy,但它的设计真的是内存渴望,所以它似乎不适合处理大数据。另一方面,python中的显式循环不是很有效。
是否有numpy的解决方案?
还有其他基于python的大数据分析框架吗?
答案 0 :(得分:2)
您可以在使用它来从阵列中选择数据子集之前就地构建选择“掩码”,而不是循环遍历项目。例如:
import numpy as np
x = np.arange(1, 100)
# x less than 75
selection = x < 75
# and greater than 35
selection &= x > 35
# and odd.
selection &= x & 1
print x[selection]
# [37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73]
这不是一个完美的解决方案,但它可能有所帮助。
答案 1 :(得分:1)
Bool存储为一个字节;除非你把你的整个记忆塞满了uint8,否则它不太可能成为一个大问题,相对而言,特别是如果你善于使用就地操作员。但是,如果您的数据几乎不适合内存,那么研究可以有效执行此类查询的磁盘存储可能会很好。 pytables浮出水面;特别是关于大数据的python框架的更一般的问题。
答案 2 :(得分:0)
另一个基于python的框架,主要使用数学是SAGE。内置了许多算法,包括排序和搜索算法。我最近参与了它的RSA建模,但也许你应该尝试一下你的问题。
答案 3 :(得分:0)
布尔选择掩码在RAM中每个空间值占用一个字节。如果您的数据可以放入RAM中,那么布线掩码也有可能适合。
您可以使用就地操作在单个布尔选择掩码中累积选择。通过这种方式,您可以应用任意数量的逻辑运算,并且需要一个选择掩码的固定RAM。
要执行就地布尔操作,您可以使用提供out
参数的Numpy Logic Functions。例如:
# (selection1 _AND_ original_array) > 3
mask = selection1(original_array)
mask = np.logical_and(mask, original_array, out=mask)
mask = np.greater(mask, 3, out=mask)
您还可以使用中缀运算符(+=
或*=
,OR和AND)执行就地操作。
如果没有足够的RAM来创建一个布尔掩码,并且所选元素的数量很少,则可以求助于按索引号选择元素。例如,numpy.nonzero()
返回每个非零元素的索引。
最后,如果您的数据不适合RAM,那么您可以使用pytables。这允许您在切片中保存和加载数据。 Pytables不仅可以为您提供非常快速的IO操作,还可以使用单个命令对磁盘上的数据集执行非常快速(复杂)的查询(请参阅pytable文档:Expr module)。然而,pytables在开始时可能有点令人生畏。所以如果你有一颗胆小的心(我并不是绝对需要它),我不建议使用它。