在大矩阵中查找满足某个条件的所有元素索引会产生MemoryError

时间:2017-10-22 04:54:23

标签: python python-3.x numpy

我的环境是Python 3.6 64bit,64位win 10 16GB ram。

我有一个有形状的ndarray(260923,)。我想找到大于阈值的所有元素的索引。我正在使用此代码,但它给出了内存错误。在任务管理器中,我可以看到我所有的ram用完了。

x_selected = x[:,x_attr]
index_right = (x_selected >thres).nonzero()[0]

我有16GB的ram并将我的PyCharm堆内存更改为6GB并且问题仍然存在。 这就是ndarray在调试器中的样子。 enter image description here

这是完整的错误: enter image description here

我该怎么办才能获得所有索引?

澄清:

x是另一个有形状的ndarray(260923,225)。 x_attr只是一个整数。所以" x_selected = x[:,x_attr]"只是从x(2d数组)中选择一列。这是x在调试器中的样子: enter image description here 当我试图找到索引时,会发生MemoreyError(我上面写的代码) 如果我缩小x_selected的行,代码就可以了。

#This does NOT work
index_left = (x_selected <= thres).nonzero()[0]
#This works however
index_left = (x_selected[0:1000] <= thres).nonzero()[0]
#This does NOT work Error: "Comparing a sparse matrix with a scalar "
#error:  " raise NotImplementedError(" >= and <= don't work with 0.")"
test = list(x[:,x_attr])
if test[1]<=thres:
    a=1

1 个答案:

答案 0 :(得分:1)

在具有1,25GB RAM的x32机器上运行WFM。因此,问题必须与您提供的特定代码无关。

一次执行一个操作,并按变量,过程和对象检查内存消耗量。内部状态可能会给你一个线索。

(这是一个很好的老问题本地化:当你丢弃代码的其他部分时,它会消失,或者扔掉所有东西然后开始添加它。一次添加/删除一半的数量会给你一个结果以对数步数。)

In [41]: x=np.random.randint(2**30,size=(260923*225),dtype=np.int64).reshape(
    ...: (260923,225))

In [42]: x.nbytes
Out[42]: 469661400

In [43]: x_selected = x[:,0]

In [44]: x_selected.nbytes
Out[44]: 2087384

In [45]: from dump import dump

In [46]: dump(x_selected)
T : [ 728497578 1063110548   71820681 ...,  701362408 1030850648  908176708]
base : [728497578 297238747 162734746 ..., 262530510 654517286 329271071]
ctypes : <numpy.core._internal._ctypes object at 0x028DEC10>
dtype : int64
flags :   C_CONTIGUOUS : False
  F_CONTIGUOUS : False
  OWNDATA : False
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
flat : <numpy.flatiter object at 0x027A3C30>
imag : [0 0 0 ..., 0 0 0]
itemsize : 8
nbytes : 2087384
ndim : 1
real : [ 728497578 1063110548   71820681 ...,  701362408 1030850648  908176708]
shape : (260923,)
size : 260923
strides : (1800,)

In [58]: x.base is None
Out[58]: False    #due to .reshape(), x does not own its memory

In [57]: x_selected.base is x.base
Out[57]: True      # but they use the same memory anyway, so x_selected does not use up extra

In [48]: c=(x_selected >1000000)

In [49]: c.nbytes
Out[49]: 260923     #c is an ndarray of bools, each bool is thus 1 byte

In [50]: n=c.nonzero()

In [59]: sys.getsizeof(n)
Out[59]: 32     #just holds a reference to the sole element

In [51]: r=n[0]

In [52]: r.nbytes
Out[52]: 1042656