Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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_Broadcast_Dimensions - Fatal编程技术网

Python 改变要一起广播的不同维度的数组

Python 改变要一起广播的不同维度的数组,python,arrays,numpy,broadcast,dimensions,Python,Arrays,Numpy,Broadcast,Dimensions,我正在寻找一种更优化的方法将(n,n)或(n,n,1)矩阵转换为(n,n,3)矩阵。我从一个(n,n,3)开始,但是当我在第二个轴上求和到(n,n)后,我的维度会减小。基本上,我想保持数组的原始大小,让第二个轴重复3次。我之所以需要它,是因为我稍后将用另一个(n,n,3)数组来广播它,但它们需要相同的维度 我目前的方法是有效的,但看起来并不优雅 a0=np.random.random((n,n)) b=a.flatten().tolist() a=np.array(zip(b,b,b)) a.s

我正在寻找一种更优化的方法将(n,n)或(n,n,1)矩阵转换为(n,n,3)矩阵。我从一个(n,n,3)开始,但是当我在第二个轴上求和到(n,n)后,我的维度会减小。基本上,我想保持数组的原始大小,让第二个轴重复3次。我之所以需要它,是因为我稍后将用另一个(n,n,3)数组来广播它,但它们需要相同的维度

我目前的方法是有效的,但看起来并不优雅

a0=np.random.random((n,n))
b=a.flatten().tolist()
a=np.array(zip(b,b,b))
a.shape=n,n,3

此设置具有所需的结果,但笨重且难以遵循。是否有一种方法可以通过复制第二个索引直接从(n,n)到(n,n,3)?或者是一种不缩小阵列尺寸的方法?

您可以首先在
a
上创建一个新轴(轴=2),然后使用
np。沿此新轴重复

np.repeat(a[:,:,None], 3, axis = 2)
或另一种方法,展平阵列,重复元素,然后重塑形状:

np.repeat(a.ravel(), 3).reshape(n,n,3)

结果比较:

import numpy as np
n = 4
a=np.random.random((n,n))
b=a.flatten().tolist()
a1=np.array(zip(b,b,b))
a1.shape=n,n,3
# a1 is the result from the original method

(np.repeat(a[:,:,None], 3, axis = 2) == a1).all()
# True

(np.repeat(a.ravel(), 3).reshape(4,4,3) == a1).all()
# True

定时,使用内置的
numpy。重复
也会显示加速:

import numpy as np
n = 4
a=np.random.random((n,n))
​
def rep():
    b=a.flatten().tolist()
    a1=np.array(zip(b,b,b))
    a1.shape=n,n,3

%timeit rep()
# 100000 loops, best of 3: 7.11 µs per loop

%timeit np.repeat(a[:,:,None], 3, axis = 2)
# 1000000 loops, best of 3: 1.64 µs per loop

%timeit np.repeat(a.ravel(), 3).reshape(4,4,3)
# 1000000 loops, best of 3: 1.9 µs per loop

None
np.newaxis
是向数组添加维度的常用方法<代码>使用(3,3,1)重塑
同样有效:

In [64]: arr=np.arange(9).reshape(3,3)
In [65]: arr1 = arr[...,None]
In [66]: arr1.shape
Out[66]: (3, 3, 1)
重复
,因为函数或方法会复制此操作

In [72]: arr2=arr1.repeat(3,axis=2)
In [73]: arr2.shape
Out[73]: (3, 3, 3)
In [74]: arr2[0,0,:]
Out[74]: array([0, 0, 0])
但你可能不需要这样做。与广播a(3,3,1)配合使用a(3,3,3)

事实上,它会用一个(3,)来播放制作(3,3,3)

所以
arr1+np.zeros(3,int)
是将(3,3,1)扩展到(3,3,3)的另一种方法

广播规则如下:

(3,3,1) + (3,) => (3,3,1) + (1,1,3) => (3,3,3)
广播会根据需要在开始处添加维度

在轴上求和时,可以使用以下参数保持原始尺寸数:

In [78]: arr2.sum(axis=2).shape
Out[78]: (3, 3)
In [79]: arr2.sum(axis=2, keepdims=True).shape
Out[79]: (3, 3, 1)
如果要从沿任意维度的数组中减去平均值,此操作非常方便:

arr2-arr2.mean(axis=2, keepdims=True)
In [78]: arr2.sum(axis=2).shape
Out[78]: (3, 3)
In [79]: arr2.sum(axis=2, keepdims=True).shape
Out[79]: (3, 3, 1)
arr2-arr2.mean(axis=2, keepdims=True)