Python 是否可以使用numpy压缩除N个维度以外的所有维度?
我想知道是否有一种方法可以将大小为1的所有维度压缩到一个数组中,而不压缩N个维度(即使这些维度的大小为1) 为什么??假设我有一个函数接收一个数组,它返回数组的矩阵积及其转置,但数组的形状未知(最大2个DIM,大小大于1,但可能有更多DIM,大小为1) 可能的矩阵形状示例:Python 是否可以使用numpy压缩除N个维度以外的所有维度?,python,numpy,Python,Numpy,我想知道是否有一种方法可以将大小为1的所有维度压缩到一个数组中,而不压缩N个维度(即使这些维度的大小为1) 为什么??假设我有一个函数接收一个数组,它返回数组的矩阵积及其转置,但数组的形状未知(最大2个DIM,大小大于1,但可能有更多DIM,大小为1) 可能的矩阵形状示例: A.shape -> (M,N) B.shape -> (M,N,1[...,1]) C.shape -> (M,1[...,1]) 为了执行矩阵积,我希望始终保持A(ndim=2)的形状 我可以使用np
A.shape -> (M,N)
B.shape -> (M,N,1[...,1])
C.shape -> (M,1[...,1])
为了执行矩阵积,我希望始终保持A(ndim=2)的形状
我可以使用np.squence(X)
,就是这样,但在C的情况下,这将导致以下问题:
import numpy as np
def my_function(arr):
arr = np.squeeze(arr)
return np.dot(arr, arr.transpose())
x = np.arange(1, 6) # shape (5,)
x = x.reshape((x.size, 1, 1)) # shape (5, 1, 1)
y = my_function(x)
print(y)
# Actual y.shape -> () [is a number]
# Expected y.shape -> (5, 5) [matrix]
我希望
np.squence()
函数有一个参数axis\u保持
。你知道有没有一种方法可以轻松做到这一点吗?我知道一些方法,但我需要最有效的方法,因为我必须多次执行这些操作。我想的解决方案之一是:
def my_squeeze(arr, axis=None, keep=0):
arr = np.squeeze(arr, axis=axis)
while arr.ndim < keep:
arr = np.expand_dims(arr, axis=-1)
return arr
如果有人知道不创建
my_squence()
函数的更好方法,我很乐意听到。使用轴挤压以保持参数
这里有一个用于一般n-dim阵列的参数,该参数具有所请求的保持这些轴的axes\u to\u keep
param-
def squeeze_generic(a, axes_to_keep):
out_s = [s for i,s in enumerate(a.shape) if i in axes_to_keep or s!=1]
return a.reshape(out_s)
样本运行-
In [105]: a = np.random.rand(3,4,5,1,1,6,1)
In [106]: squeeze_generic(a, axes_to_keep=(3,4)).shape
Out[106]: (3, 4, 5, 1, 1, 6)
In [107]: squeeze_generic(a, axes_to_keep=(3,4,6)).shape
Out[107]: (3, 4, 5, 1, 1, 6, 1)
# For cases when axes_to_keep lists axes that aren't singleton
In [108]: squeeze_generic(a, axes_to_keep=(0,1)).shape
Out[108]: (3, 4, 5, 6)
解决您的问题以保持前两个轴
因此,要解决保留前两个轴的具体情况,它将是——
squeeze_generic(a, axes_to_keep=range(2))
让我们看看这方面的示例案例-
In [55]: a = np.random.rand(3,5)
In [56]: squeeze_generic(a, axes_to_keep=range(2)).shape
Out[56]: (3, 5)
In [57]: a = np.random.rand(3,5,1)
In [58]: squeeze_generic(a, axes_to_keep=range(2)).shape
Out[58]: (3, 5)
In [59]: a = np.random.rand(3,1)
In [60]: squeeze_generic(a, axes_to_keep=range(2)).shape
Out[60]: (3, 1)
如果保证第二个轴之后的所有轴都是单轴(长度轴=1)如果有,那么简单的重塑也可以完成这项工作-
a.reshape(a.shape[0],-1)
你试过np.挤压(arr,-1)
?@Chris是的,当输入形状为(M,N)
时会给我一个错误,因为被挤压的轴的长度不是1。另外,如果我有输入形状(M,N,1,1,1)
,它只会挤压最后一个轴,我需要挤压除前2个以外的每个轴(在这种情况下)。效率不是什么大问题。像这样的形状更改只会生成一个视图,与复制和计算相比几乎没有成本。请查看expand\u dims
的代码。请注意它是如何构造元组并在重塑
中使用它的。这就是@Divakar正在做的事情。@hpaulj哦,我没想到expand\u dims
会使用restrape
。我认为它会使用更“有效”的东西。我想我的解决方案不太好,因为是while循环。在大多数情况下,重塑
不会产生效率低下的效果,它会生成具有新形状和步幅的视图。无副本或元素计算。谢谢。我认为这是最好的解决办法。
a.reshape(a.shape[0],-1)