python - 处理 python 数组中的维度崩溃

标签 python arrays numpy dimensions

我在使用 NumPy 时遇到的一个反复出现的错误是,尝试索引数组失败,因为数组的某个维度是单例,因此该维度被删除并且无法索引。这在设计用于操作任意大小的数组的函数中尤其成问题。我正在寻找最便宜、最通用的方法来避免这个错误。

这是一个例子:

import numpy as np
f = (lambda t, u, i=0: t[:,i]*u[::-1])
a = np.eye(3)
b = np.array([1,2,3])
f(a,b)
f(a[:,0],b[1])

第一次调用按预期工作。第二次调用以两种方式失败:1) t无法通过 [:,0] 进行索引因为它有形状(3,)和 2) u根本无法索引,因为它是标量。

以下是我想到的修复:

1) 使用np.atleast_1dnp.atleast_2d等(可能带有条件以确保尺寸顺序正确)在 f 内以确保所有参数都具有所需的尺寸。这排除了 lambda 的使用,并且可能需要一些我不想用的行。

2)而不是写f(a[:,0],b[1])上面,使用f(a[:,[0]],b[[1]]) 。这很好,但我总是必须记住放入额外的括号,如果索引存储在变量中,您可能不知道是否应该放入额外的括号。例如:

idx = 1
f(a[:,[0]],b[[idx]])
idx = [2,0,1]
f(a[:,[0]],b[idx])

在这种情况下,您似乎必须调用 np.atleast_1didx首先,这可能比输入 np.atleast_1d 更麻烦。在函数中。

3)在某些情况下,我可以不放入索引而逃脱惩罚。例如:

f = lambda t, u: t[0]*u
f(a,b)
f(a[:,0],b[0])

这是有效的,并且显然是应用时最灵活的解决方案。但它并不适用于所有情况(特别是,您的尺寸必须以正确的顺序开始)。

那么,还有比上述更好的方法吗?

最佳答案

有很多方法可以避免这种行为。

首先,每当您使用 slice 而不是整数索引 np.ndarray 的维度时,输出的维度数将与输入的:

import numpy as np

x = np.arange(12).reshape(3, 4)
print x[:, 0].shape               # integer indexing
# (3,)

print x[:, 0:1].shape             # slice
# (3, 1)

这是我避免该问题的首选方法,因为它很容易从单元素选择推广到多元素选择(例如 x[:, i:i+1] x[:, i:i+n])。

正如您已经提到的,您还可以通过使用任何整数序列来索引维度来避免维度损失:

print x[:, [0]].shape             # list
# (3, 1)

print x[:, (0,)].shape            # tuple
# (3, 1)

print x[:, np.array((0,))].shape  # array
# (3, 1)

如果您选择坚持使用整数索引,则始终可以使用np.newaxis(或等效的None)插入新的单一维度:

print x[:, 0][:, np.newaxis]
# (3, 1)

print x[:, 0][:, None]
# (3, 1)

或者您可以手动将其重新调整为正确的大小(此处使用 -1 自动推断第一个维度的大小):

print x[:, 0].reshape(-1, 1).shape
# (3, 1)

最后,您可以使用 np.matrix 而不是 np.ndarraynp.matrix 的行为更像 MATLAB 矩阵,每当您使用整数进行索引时,都会保留单个维度:

y = np.matrix(x)
print y[:, 0].shape
# (3, 1)

但是,您应该知道有一个 number of other important differencesnp.matrixnp.ndarray 之间,例如 * 运算符对数组执行元素乘法,但对矩阵执行矩阵乘法。在大多数情况下,最好坚持使用 np.ndarrays

关于python - 处理 python 数组中的维度崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24441326/

相关文章:

python - 是否可以将日期时间列添加到多对多字段?

python - 非比例随机样本

Python pickle : Unclear "AttributeError: can' t set attribute"

java - 是否有更短的代码或更简单的方法将元素添加到不同大小的多个数组中?

python-3.x - 使用 numpy arange 创建一系列 float

返回整数的 Python 运算符

c++ - C++-检查单词是否为结构数据类型的回文

python - 将这两个向量相乘的大多数 Pythonic 方法?

python - 填充蒙版框架中的孔/ block

javascript - 选中时从数组中删除值