重新排列一个大的numpy数组中的行将某些行归零。怎么解决?

时间:2014-09-11 16:45:12

标签: python 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的RAM,所以我不认为内存是一个约束。谢谢你的提示!

2 个答案:

答案 0 :(得分:1)

我强烈怀疑你的numpy版本。我怀疑它可能是this bug的一种表现形式,你可以看到将一个大数组设置为静默值并输出零。也许可以通过numpy版本和更多时间来确定它。

我在这里写了一个测试脚本,它应该生成类似于你描述的数据集(下面为了完整性而复制了代码)。我无法重现原始问题..

我可以使用np.array设置59022 x 84122 dtype=np.uint16,但感兴趣的命令会给出内存不足的消息。所以我 am 内存有限,因此无法测试您提供的确切值。

但是,如果我将宽度降低到54122,代码将按预期工作(不会在行中输出零> 7966)。

我的numpy版本是

  

numpy.version.version ==' 1.8.2'

我的python版本和系统如下:

  

Python 3.3.0(v3.3.0:bd8afb90ebf2,Sep 29 2012,10:57:17)[MSC v.1600 64 bit(AM D64)] on 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

答案 1 :(得分: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)
相关问题