Python 如何安全地将整数矩阵预先分配为numpy中的索引矩阵

Python 如何安全地将整数矩阵预先分配为numpy中的索引矩阵,python,numpy,Python,Numpy,我想预先分配一个整数矩阵来存储迭代中生成的索引。在MATLAB中,这可以通过IXS=zero(r,c)在之前为循环获得,其中r和c是行数和列数。因此,后续for循环中的所有索引都可以分配到IXS中,以避免动态分配。例如,如果我在代码中意外地选择了一个0,那么从矩阵中选择元素时选择这些索引的方法是错误的,可能会出现错误 但在numpy中,0或其他负值也可以用作索引。例如,如果我将IXS预先分配为IXS=np.zeros([r,c],dtype=int),则在numpy中。在for循环中,以前分配到

我想预先分配一个整数矩阵来存储迭代中生成的索引。在MATLAB中,这可以通过
IXS=zero(r,c)
之前为
循环获得,其中
r
c
是行数和列数。因此,后续
for
循环中的所有索引都可以分配到
IXS
中,以避免动态分配。例如,如果我在代码中意外地选择了一个0,那么从矩阵中选择元素时选择这些索引的方法是错误的,可能会出现错误

但在numpy中,0或其他负值也可以用作索引。例如,如果我将
IXS
预先分配为
IXS=np.zeros([r,c],dtype=int)
,则在numpy中。在
for
循环中,以前分配到
IXS
的索引指定的子矩阵可以通过MATLAB中的
X(:,IXS(IXS~=0))
获得,但是如果在numpy中以相同的方式执行选择,第一行/列可能会丢失

此外,在具有大型矩阵运算的大型程序中,预分配对于加快计算速度非常重要,并且很容易定位错误索引引起的错误,因为在MATLAB中可能选择0。在numpy中,如果我选择了一个数组,例如
X[:,IXS[:n]]
错误
n
,则不会发生错误。我必须花很多时间来检查错误在哪里。更糟糕的是,如果最终结果不是那么奇怪,我可能会忽略这个bug。这总是发生在我的程序中。因此,我不得不一次又一次地调试代码


我想知道有没有一种安全的方法可以在numpy中预先分配这样的索引矩阵?

在numpy中,matlb
零的等价物是:

返回给定形状和类型的新数组,并用零填充


numpy中matlb
零的等效值为:

返回给定形状和类型的新数组,并用零填充


用明显太大的值填充索引数组如何:

In [156]: x=np.array([1,2,3,4,5])
In [157]: idx=np.full(6,999,dtype=int)
In [158]: idx[:3]=[1,0,4]
In [159]: idx
Out[159]: array([  1,   0,   4, 999, 999, 999])
In [160]: x[idx[:3]]
Out[160]: array([2, 1, 5])
In [161]: x[idx[:4]]
...
IndexError: index 999 is out of bounds for axis 1 with size 5

用明显太大的值填充索引数组如何:

In [156]: x=np.array([1,2,3,4,5])
In [157]: idx=np.full(6,999,dtype=int)
In [158]: idx[:3]=[1,0,4]
In [159]: idx
Out[159]: array([  1,   0,   4, 999, 999, 999])
In [160]: x[idx[:3]]
Out[160]: array([2, 1, 5])
In [161]: x[idx[:4]]
...
IndexError: index 999 is out of bounds for axis 1 with size 5

如果您真的想通过这种方式捕获错误,请使用NaN初始化索引

IXS=np.full((r,c),np.nan,dtype=int)


这将始终引发一个
索引器

如果您真的希望通过这种方式捕获错误,请使用NaN初始化索引

IXS=np.full((r,c),np.nan,dtype=int)


这将始终引发一个
索引器
使用
numpy.ma.masked\u数组

IXS=np.ma.masked_values(np.zeros((3,4),dtype=int),0)

masked_array(data =
 [[-- -- -- --]
 [-- -- -- --]
 [-- -- -- --]],
             mask =
 [[ True  True  True  True]
 [ True  True  True  True]
 [ True  True  True  True]],
       fill_value = 0)
现在,如果设置一个值,可以将其用作索引:

a=np.arange(10)
IXS[2,2]=5
a[IXS[2,2]]

5
但如果你没有:

IXS[0,0]

masked

a[IXS[0,0]]

IndexError: arrays used as indices must be of integer (or boolean) type

使用
numpy.ma.masked_数组

IXS=np.ma.masked_values(np.zeros((3,4),dtype=int),0)

masked_array(data =
 [[-- -- -- --]
 [-- -- -- --]
 [-- -- -- --]],
             mask =
 [[ True  True  True  True]
 [ True  True  True  True]
 [ True  True  True  True]],
       fill_value = 0)
现在,如果设置一个值,可以将其用作索引:

a=np.arange(10)
IXS[2,2]=5
a[IXS[2,2]]

5
但如果你没有:

IXS[0,0]

masked

a[IXS[0,0]]

IndexError: arrays used as indices must be of integer (or boolean) type

您需要添加一两个示例。你的担心并不明显
x=np。零([r,c],int)
是一个普通数组,包含r行、c列和0。和整数数据类型。什么是索引矩阵
?谢谢。我已经编辑了我的问题,我仍然感到困惑。在MATLAB(我可以用倍频程测试)和numpy中显示一个小示例。事实上,MATLAB索引从1:n开始运行,这意味着您可以使用0作为某种“未分配”值,其中as numpy索引从0开始,它将
-1
理解为
end-1
。但通常这不是问题。创建和使用这个
IXS
数组的方式有些不寻常。简单的例子是,假设
IXS=[1,2,4,0,0]
x=[1,2,3,4,5]
。子数组的欧几里德范数,如果我在MATLAB中使用
norm(x(IXS(1:4))
,可能会出现错误,但在numpy中,如果我使用
np.linalg.norm(x[IXS[:4]])
,则不会出现错误。显然,这是不正确的。如果我没有以正确的方式使用IX,或者没有像示例中那样为拾取子阵列创建错误的索引,那么您是对的。我想要的是,如果出现这种情况,可以提出错误,这样我就可以很容易地找到错误。在我的程序中,这一点很重要,因为需要执行很多矩阵运算。您需要添加一两个示例。你的担心并不明显
x=np。零([r,c],int)
是一个普通数组,包含r行、c列和0。和整数数据类型。什么是索引矩阵
?谢谢。我已经编辑了我的问题,我仍然感到困惑。在MATLAB(我可以用倍频程测试)和numpy中显示一个小示例。事实上,MATLAB索引从1:n开始运行,这意味着您可以使用0作为某种“未分配”值,其中as numpy索引从0开始,它将
-1
理解为
end-1
。但通常这不是问题。创建和使用这个
IXS
数组的方式有些不寻常。简单的例子是,假设
IXS=[1,2,4,0,0]
x=[1,2,3,4,5]
。子数组的欧几里德范数,如果我在MATLAB中使用
norm(x(IXS(1:4))
,可能会出现错误,但在numpy中,如果我使用
np.linalg.norm(x[IXS[:4]])
,则不会出现错误。显然,这是不正确的。如果我没有以正确的方式使用IX,或者没有像示例中那样为拾取子阵列创建错误的索引,那么您是对的。我想要的是,如果出现这种情况,可以提出错误,这样我就可以很容易地找到错误。在我的程序中,这一点很重要,因为需要执行很多矩阵运算。谢谢。这就是我在代码中所做的,因为在计算过程中矩阵的大小是固定的。但我认为这不够安全,因为在其他情况下,小矩阵生成的索引可以用于大矩阵,所以我必须确定多大的矩阵足够大。也许
np.full(6,np.inf,dtype=int)
更合适,但是如果一个数组将来有超过2147483648个元素,我该怎么办呢?所以关于最大数组维度和内存限制的问题:谢谢。这就是我在代码中所做的,因为在计算过程中矩阵的大小是固定的。但我认为这不够安全,因为在其他情况下,小矩阵生成的索引可以用于大矩阵,所以我必须确定