Numpy:使用reshape或newaxis添加尺寸

时间:2015-02-07 18:15:45

标签: python numpy

可以使用ndarray.reshapenumpy.newaxis向数组添加新维度。他们似乎都创造了一个观点,使用一个而不是另一个是否有任何理由或优势?

>>> b
array([ 1.,  1.,  1.,  1.])
>>> c = b.reshape((1,4))
>>> c *= 2
>>> c
array([[ 2.,  2.,  2.,  2.]])
>>> c.shape
(1, 4)
>>> b
array([ 2.,  2.,  2.,  2.])
>>> d = b[np.newaxis,...]
>>> d
array([[ 2.,  2.,  2.,  2.]])
>>> d.shape
(1, 4)
>>> d *= 2
>>> b
array([ 4.,  4.,  4.,  4.])
>>> c
array([[ 4.,  4.,  4.,  4.]])
>>> d
array([[ 4.,  4.,  4.,  4.]])
>>> 

`

2 个答案:

答案 0 :(得分:14)

我没有看到太大差异的证据。您可以对非常大的阵列进行时间测试。基本上都是摆弄形状,可能是步幅。 __array_interface__是访问此信息的好方法。例如:

In [94]: b.__array_interface__
Out[94]: 
{'data': (162400368, False),
 'descr': [('', '<f8')],
 'shape': (5,),
 'strides': None,
 'typestr': '<f8',
 'version': 3}

In [95]: b[None,:].__array_interface__
Out[95]: 
{'data': (162400368, False),
 'descr': [('', '<f8')],
 'shape': (1, 5),
 'strides': (0, 8),
 'typestr': '<f8',
 'version': 3}

In [96]: b.reshape(1,5).__array_interface__
Out[96]: 
{'data': (162400368, False),
 'descr': [('', '<f8')],
 'shape': (1, 5),
 'strides': None,
 'typestr': '<f8',
 'version': 3}

使用与原始缓冲区相同的data缓冲区创建视图。相同的形状,但重塑不会改变stridesreshape可让您指定order

.flags显示C_CONTIGUOUS标志的差异。

reshape可能会更快,因为它的更改次数更少。但无论哪种方式,操作都不应该影响更大计算的时间。

e.g。对于大b

In [123]: timeit np.outer(b.reshape(1,-1),b)
1 loops, best of 3: 288 ms per loop
In [124]: timeit np.outer(b[None,:],b)
1 loops, best of 3: 287 ms per loop

有趣的观察:b.reshape(1,4).strides -> (32, 8)

这是我的猜测。 .__array_interface__正在显示一个基础属性,而.strides更像是一个属性(尽管它可能都隐藏在C代码中)。默认基础值为None,当需要进行计算(或使用.strides显示)时,它会根据形状和项目大小进行计算。 32是到第1行末尾的距离(4x8)。 np.ones((2,4)).strides(32,8)中具有相同的None(和__array_interface__

另一方面,

b[None,:]正准备播放阵列。广播时,重复使用现有值。这就是0(0,8)的作用。

In [147]: b1=np.broadcast_arrays(b,np.zeros((2,1)))[0]

In [148]: b1.shape
Out[148]: (2, 5000)

In [149]: b1.strides
Out[149]: (0, 8)

In [150]: b1.__array_interface__
Out[150]: 
{'data': (3023336880L, False),
 'descr': [('', '<f8')],
 'shape': (2, 5),
 'strides': (0, 8),
 'typestr': '<f8',
 'version': 3}

b1显示的内容与np.ones((2,5))相同,但只有5个项目。

np.broadcast_arrays/numpy/lib/stride_tricks.py中的一项功能。它使用同一文件中的as_strided。这些函数直接使用shape和strides属性。

答案 1 :(得分:1)

numpy.newaxis上使用ndarray.reshape的一个原因是当您要使用多个“未知”维度时。因此,例如,对于以下数组:

>>> arr.shape
(10, 5)

这有效:

>>> arr[:, np.newaxis, :].shape
(10, 1, 5)

但这不是:

>>> arr.reshape(-1, 1, -1)
...
ValueError: can only specify one unknown dimension