2016-08-22 22 views
4

我是python数据分析的新手,并试图找出如何将多维数组操作到不同的维度。在线教程或论坛不解释如何指定“newshape”的参数numpy.reshape(a, newshape, order='C')了解如何为numpy的整形指定newshape参数()

这里是我想了解的一个示例。这将是非常有益的,如果有人可以解释第4行

import numpy as np 
a1 = np.arrange(8).reshape((8,1)) 
b = np.repeat(a1,8,axis=1) 
c = b.reshape(2,4,2,4)    # line 4 

回答

3

从一周前的一个类似的问题:How to understand ndarray.reshape function?

np.reshape(a, newshape)被重铸为a.reshape(newshape)。但a.reshape是一种内置的编译方法。因此,它如何处理newshape的细节是隐藏的(对于Python程序员)。

这些示例显示newshape可以是元组或单独的数字。但从某种意义上说,即使是单独的数字情况下也使用元组。函数的参数作为元组传递。

这可能是最明显的索引。 a[:,1,3]由口译员翻译成a.__getitem__((slice(None),1,3))致电。而且实际上a[(:,1,3)]是允许的,因为是ind = (slice(None),1,3); a[ind]

可以很容易地编写自己的函数,使得()可选的额外层:

In [58]: def foo(*args): 
    ...:  if len(args)==1: 
    ...:   args = args[0] 
    ...:  print(args) 
    ...:  

In [59]: foo(1,2,3) 
(1, 2, 3) 

In [60]: foo((1,2,3)) 
(1, 2, 3) 

我需要完善多一点对待这2个相同的情况下:

In [61]: foo(1) 
1  
In [62]: foo((1,)) 
(1,) 

如果我将函数定义为def foo(arg):,那么如果我想给它几个数字,就必须使用元组。

希望这可以让大多数有经验的Python程序员为什么不被这些差异所困扰。通常,元组只是将值分组的一种便利方式。它可以增加清晰度,但并不总是需要。编码器可以朝着任何方向发展 - 无论是否存在,还是做了大量工作。

===================

的重塑方法在numpy/core/src/multiarray/methods.c定义(在GitHub的numpy的储存库)。虽然写在c它似乎是

def reshape(self, *args, **kwargs): 
    n = len(args) 
    if n<=1: 
     newshape = <parse args[0] in one way> 
    else: 
     newshape = <parse args in another way> 
    return PyArray_Newshape(self, newshape, order) 

相当于在任何情况下,它正在分析等等这些都是一样的:

shape=(2,3) 
np.arange(6).reshape(shape) 
np.arange(6).reshape(*shape) 
np.arange(6).reshape(2,3) 
np.arange(6).reshape((2,3)) 
np.arange(6).reshape((2,)+(3,)) 
1

newshape参数有一个元组(或兼容的东西),以numpy.reshape传递。但这里有一个问题:传递给numpy.ndarray.reshape的所有非关键字参数(例如,在本例中为b.reshape)将被参数newshape捕获。这意味着下面的是等价的,有效的:

# b = np.random.rand(2*4*2*4) 
np.reshape(b,(2,4,2,4)) 
np.ndarray.reshape(b,(2,4,2,4)) 
np.ndarray.reshape(b,2,4,2,4) 
b.reshape((2,4,2,4)) 
b.reshape(2,4,2,4) 

虽然这将引发一个错误:

np.reshape(b,2,4,2,4) 

的关键区别在于np.reshapenp.ndarray.reshape是不同的动物,b.reshape是的绑定版本后者。


你也应该比较help(np.reshape)

reshape(a, newshape, order='C') 
    Gives a new shape to an array without changing its data. 

help(b.reshape)

a.reshape(shape, order='C') 

Returns an array containing the same data with a new shape. 

正如你所看到的,np.reshape没有关于特定阵列的任何信息,所以如果你想要重塑使用它的东西,你必须明确地将它作为第一个参数传递。另一方面,b.reshape绑定到变量b,因此只需要给定一个新形状,并且可以选择order关键字参数。

0

这是另一个理解数组的shape的角度,如果这是你要求的一部分。 shape参数(2, 4, 2, 4)指定了阵列四个不同轴中每个轴的长度。如果你在概念上将其视为列表清单,那么它就意味着从最外列表到最内列表的长度。例如,对于您的阵列c,如果您检查:

len(c) 
# 2 

len(c[0])   # same result if you check c[1] 
# 4 

len(c[0][0]) 
# 2 

len(c[0][0][0]) 
# 4 

这与匹配形状参数。或者可以是一个更好的例子是2D阵列,其是矩阵:

a = np.array(range(9)) 
a 
# array([0, 1, 2, 3, 4, 5, 6, 7, 8]) 

b = a.reshape(3,3) 
b 
# array([[0, 1, 2], 
#  [3, 4, 5], 
#  [6, 7, 8]]) 

正如你可以看到,b具有相同的数据作为a但具有两层维结构,如在形状指定的每个具有3长度参数。现在如果你检查:

len(b) 
# 3 

len(b[0]) 
# 3 

它给出了形状参数。