Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理python数组中的维度折叠_Python_Arrays_Numpy_Dimensions - Fatal编程技术网

处理python数组中的维度折叠

处理python数组中的维度折叠,python,arrays,numpy,dimensions,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]) 第一个调用按预

我在使用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) 在
f
中使用
np.atleast_1d
np.atleast_2d
等(可能带有条件以确保尺寸顺序正确)以确保所有参数都具有所需的尺寸。这就排除了lambdas的使用,并且可以使用一些我不需要的行

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])
在这种情况下,您似乎必须首先在
idx
上调用
np.atleast_1d
,这可能比在函数中放入
np.atleast_1d
更麻烦

3) 在某些情况下,我可以不加索引而侥幸逃脱。例如:

f = lambda t, u: t[0]*u
f(a,b)
f(a[:,0],b[0])
这是可行的,而且显然是最巧妙的解决方案。但这并不是在所有情况下都有帮助(特别是,你的维度必须以正确的顺序开始)


那么,有没有比上述更好的方法呢?

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

首先,每当使用
切片而不是整数索引到
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]
vs
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
)插入新的单例维度:

或者,您可以手动将其重塑为正确的大小(此处使用
-1
自动推断第一个尺寸的大小):

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

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

但是,您应该注意到,
np.matrix
np.ndarray
之间存在一个关系,例如,
*
运算符对数组执行元素乘法,但对矩阵执行矩阵乘法。在大多数情况下,最好坚持使用
np.ndarrays

许多numpy函数都有许多行python代码,在执行中心操作之前,这些代码会重新塑造和处理输入。例如,看看
至少1d
做了什么(它有10行长)。我感觉到了你的痛苦。我通常是这样处理的:首先我存储输入形状并检查输入是否为标量,然后我应用类似于
np的东西。至少\u 1d
并进行计算,最后我重塑结果以匹配输入形状(例如,转换回标量)。缺点:这是很多陈词滥调。优点:更灵活的界面,对调用方的惊喜更少。我认为作为特定领域库的一部分的一个相当通用的函数是值得的。
print x[:, 0].reshape(-1, 1).shape
# (3, 1)
y = np.matrix(x)
print y[:, 0].shape
# (3, 1)