重新排列大numpy数组中的行时,导致某些行变为零,如何解决?
我正在使用numpy处理以下数据(所有矩阵的单元格都是非负的):
>>> X1.shape
(59022, 16)
>>> X3.shape
(59022, 84122)
>>> ind.shape
(59022,)
>>> np.max( ind )
59021
>>> np.min( ind )
0
>>> len( set ( ind.tolist() ) )
59022
简单来说,ind只是用来重新排列任意一个矩阵的行。问题是,在较小的数组(X1)中重新排列行的操作效果很好,但在较大的数组(X2)中进行同样的操作时,某个点以下的所有行都变成了零。以下是我的操作步骤:
>>> np.nonzero( np.sum( X3, axis=1 ) )[0].shape
(59022,)
现在我们来看看如果重新排列行会发生什么:
>>> np.nonzero( np.sum( X3[ ind, : ], axis=1 ) )[0].shape
(7966,)
但是对于较小的矩阵,一切都运行得很好:
>>> np.nonzero( np.sum( X1, axis=1 ) )[0].shape
(59022,)
>>> np.nonzero( np.sum( X1[ ind, : ], axis=1 ) )[0].shape
(59022,)
我在想我可以尝试使用稀疏矩阵,但我只是想知道我是否能让这个操作正常工作。我有256GB的内存,所以我觉得内存不是问题。谢谢你的建议!
2 个回答
0
你有没有试过把你的数据放到一个叫做pandas的数据框架里,然后给一个新列应用一个lambda函数,最后根据这个新列进行排序呢?
import pandas as pd
df = pd.DataFrame(yournumpyarray)
df.columns=['col1','col2',...,'coln']
df['coln+1'] = df['col1'].apply(lambda x: myfunction(x)) + df['col2'].apply...
df = df.sort('coln+1')
df = df.drop('coln+1', 1)
1
我很怀疑你的numpy版本。 我觉得这可能是这个bug的表现,里面提到设置一个大数组的值时会悄悄失败,结果输出全是零。也许可以通过检查numpy的版本和花点时间来确认这个问题。
我在这里写了一个测试脚本,应该能生成与你描述的类似的数据集(下面复制了代码以便完整)。我无法重现原来的问题。
我可以创建一个59022 x 84122的np.array
,并且设置dtype=np.uint16
,但是我关注的命令却提示内存不足。所以我确实受限于内存,无法测试你给出的确切值。
不过,如果我把宽度降到54122,代码就能正常工作(在行数大于7966时不会输出零)。
我的numpy版本是
numpy.version.version == '1.8.2'
我的python版本和系统信息如下:
Python 3.3.0 (v3.3.0:bd8afb90ebf2, 2012年9月29日, 10:57:17) [MSC v.1600 64位 (AMD64)] 在win32上
脚本代码
import numpy as np
import os
# Function to make some test data that will fit in memory...
def makeX(ind,width):
rowcount = len(ind)
Xret = np.ones((rowcount,width),dtype=np.uint16)
col0 = ind.copy()
col0 = col0.reshape((rowcount,1))
np.random.shuffle(col0)
for r in range(len(Xret)):
Xret[r] = bytearray(os.urandom(width))
Xret[r][0] = col0[r]
return Xret
X3width = 54122 # if this is 84122, the last line fails with MemoryError on my box
# (16GB memory ~13 available)
ind = np.array(range(59022))
X1 = makeX(ind,16)
X3 = makeX(ind,54122)
print('Shapes of ind, X1 and X3')
print(ind.shape)
print(X1.shape)
print(X3.shape)
print('Contents of ind, X1 and X3')
print(ind)
print(X1)
print(X3)
print('Shape of np.nonzero( np.sum( X3, axis=1 ) )[0]')
print(np.nonzero( np.sum( X3, axis=1 ) )[0].shape)
print('Shape of np.nonzero( np.sum( X3, axis=1 ) )[0]')
print(np.nonzero( np.sum( X3[ ind, : ], axis=1 ) )[0].shape)
#This outputs (59022,) as expected