在NumPy中加速代码

在NumPy中加速代码,numpy,scipy,Numpy,Scipy,我有一个二维numpy阵列(光栅_数据),光栅大小为100万*100万。 我想将该光栅分为两类,如下所示: class_A = np.where((raster_data >= 5.23) & (raster_data < 8.55),raster_data,np.nan) class_B = np.where((raster_data >= 8.55) & (raster_data < 10.0),raster_data,np.nan) class\u

我有一个二维numpy阵列(光栅_数据),光栅大小为100万*100万。 我想将该光栅分为两类,如下所示:

class_A = np.where((raster_data >= 5.23) & (raster_data < 8.55),raster_data,np.nan)
class_B = np.where((raster_data >= 8.55) & (raster_data < 10.0),raster_data,np.nan)
class\u A=np.其中((光栅数据>=5.23)和(光栅数据<8.55),光栅数据,np.nan)
B类=np.其中((光栅数据>=8.55)和(光栅数据<10.0),光栅数据,np.nan)
然而,由于数据量非常大,我收到内存错误。 我怎样才能按照我的要求对光栅进行分类?
我已经尝试使用16GB RAM和64位NumPy。

您可以尝试布尔索引和就地操作以节省内存:

>>> class_A = raster_data.copy()
>>> class_B = raster_data.copy()
>>> mask = raster_data < 5.23
>>> mask |= raster_data >= 8.55
>>> class_A[mask] = np.nan
>>> mask = raster_data < 8.55
>>> mask |= raster_data >= 10
>>> class_B[mask] = np.nan
>class\u A=graster\u data.copy()
>>>class_B=光栅_数据.copy()
>>>遮罩=光栅_数据<5.23
>>>遮罩|=光栅_数据>=8.55
>>>A类[屏蔽]=np.nan
>>>遮罩=光栅_数据<8.55
>>>遮罩|=光栅_数据>=10
>>>B类[屏蔽]=np.nan

如果您的数据集确实像您指定的那么大,您将需要某种形式的磁盘存储和核心外计算


这完全取决于你想用这个面具做什么,但是看看pytables;它允许对如此大的阵列进行有效的存储和操作。

这就是使用pytables的方法。虽然我希望你有耐心,有很多空间

import tables as tb
import numpy as np
import time

f = tb.openFile('humongusFile.h5', 'w')

n = 100000
x = f.createCArray(f.root, 'x', tb.Float16Atom(), (n,n), filters=tb.Filters(5, 'blosc'))



t0 = time.time()

for i in range(n):
    x[i] = np.random.random_sample(n)* 10
x.flush()  # dump data to disk

t1 = time.time()
print t1 - t0
print "Done creating test data"

y1 = f.createCArray(f.root, 'y1', tb.Float16Atom(), (n,n), filters=tb.Filters(5, 'blosc'))
y2 = f.createCArray(f.root, 'y2', tb.Float16Atom(), (n,n), filters=tb.Filters(5, 'blosc'))

t2 = time.time()
print t2 - t1
print "Done creating output array"

expr = tb.Expr("where((x >= 5.23) & (x < 8.55), x, 0)")
expr.setOutput(y1)

expr2 = tb.Expr("where((x >= 5.23) & (x < 8.55), x, 0)")
expr2.setOutput(y2)

t3 = time.time()
print t3 - t2
print "Starting evaluating first output"
expr.eval()
print "Starting evaluating second output"
expr2.eval()
print "Done"
t4 = time.time()
print t4 - t3
将表作为tb导入
将numpy作为np导入
导入时间
f=tb.openFile('humongusFile.h5','w')
n=100000
x=f.createCArray(f.root,'x',tb.Float16Atom(),(n,n),filters=tb.filters(5,'blosc'))
t0=时间。时间()
对于范围(n)中的i:
x[i]=np.随机.随机样本(n)*10
x、 flush()#将数据转储到磁盘
t1=时间。时间()
打印t1-t0
打印“创建测试数据完成”
y1=f.createCArray(f.root,'y1',tb.Float16Atom(),(n,n),filters=tb.filters(5,'blosc'))
y2=f.createCArray(f.root,'y2',tb.Float16Atom(),(n,n),filters=tb.filters(5,'blosc'))
t2=时间。时间()
打印t2-t1
打印“创建输出数组完成”
expr=tb.expr(“其中((x>=5.23)和(x<8.55),x,0)”
表达式设置输出(y1)
expr2=tb.Expr(“其中((x>=5.23)和(x<8.55),x,0)”
expr2.setOutput(y2)
t3=时间。时间()
打印t3-t2
打印“开始评估第一个输出”
expr.eval()
打印“开始评估第二次输出”
expr2.eval()
打印“完成”
t4=时间。时间()
打印t4-t3

当问题出在内存上时,为什么标题速度会变慢?一个由1e6 x 1e6项组成的数组有一万亿(1e12)项。即使每个项目存储一个位,也需要125 GB来存储
光栅_数据
数组,单精度浮点需要4 TB的内存…答案取决于要对类执行什么操作、类中有多少元素(稀疏矩阵?)以及如何存储数据。数据是否以某种方式稀疏?首先,你是如何获得1M*1M图像的?与其他人一样,使用如此大小的图像有点奇怪。不,
mask
这里是OP问题中条件的否定:他正在选择保存
graster_数据的位置
值,我正在寻找通过
np.nan
重新计算值的位置。还请注意,我不是在
&
-ing这两个条件,而是在
|-
-ing它们,因为
~(a&b)==a | ~b
。您对PyTables的实现非常好,但是在表达式中不可能使用np.nan值代替零吗?@rockpy我不确定PyTables是否支持nan值。但您通常可以“定义”一个数据中永远不会出现的值作为nan。