Python语言中 reshape排序参数order详解

前言

使用Pyton时发现网上关于reshape方法的文章一般都比较简单,尤其是关于排序的问题很少涉及或讲解的不清楚,所以特整理了reshape的用法,供大家参考。


1.reshape的语法

reshape在不更改数组数据的情况下为数组提供新形状,即先将数组拉伸成一维数组,再按order的顺序重组数组维度。

在Python的ndarray和NumPy中都有reshape方法,使用方法类似,仅引用方式不同。其语法格式如下:

numpy.reshape(a, newshape, order='C')

ndarray.reshape( newshape, order='C')

两种语法的不同仅是一个以函数的方式将数组作为一个参数传入,而另一个则是以数组函数的方式调用。

注意:newshape是新数组的形状,必须是整数或整数元组,如(2,3)。

2.NumPy中reshape的经典用法

np.reshape(a, (x, y))

代码如下:

import numpy as np
a = np.arange(1,13) #生成一个12个元素一维数组
b = np.reshape(a,(6,2))  #将12个元素一维数组转换为6x2的二维数组
print(a)
print()

 运行结果如下:

 注意:重组后的数组元素数量必须保证与重组前的元素数量完全相等,否则报错。

例如以下代码将生成的元素改为11个:

import numpy as np
a = np.arange(1,12) #生成一个11个元素一维数组
b = np.reshape(a,(6,2))  #将12个元素一维数组转换为6x2的二维数组
print(a)
print()

 运行结果如下(报错):

3.ndarray中reshape的经典用法

a.reshape(x, y)

代码如下:

a = np.arange(1,13) #生成一个12个元素一维数组
b = a.reshape(6,2)  #将12个元素一维数组转换为6x2的二维数组
print(a)
print()
print(b)

 运行结果如下:

 对比NumPy中reshape方法的使用可以发现,在ndarray中使用reshape实际上是省略了一层括号,应当是a.reshape((x, y)),在后面可以看到,当使用order参数时必须按照完整格式书写,这种现象在Python中能够经常看到,这也充分说明了Python的灵活性。

4.reshape方法对多维数组的重组方法

由于NumPy和ndarray的语法完全相同,下面将不再分别举例。而且在Python文档中ndarray.reshape也仅是一个简单的文档,连例子都没有,而是让你去参照numpy.reshape的文档(有兴趣可以参见后附的ndarray.reshape原始说明文档)。


当源数组是多维数组的时候,reshape方法先将数组拉伸成为一维数组,然后再按照newshape参数重组为新的多维数组(特殊的情况是newshape=数组元素数量,这时就相当于将多维数组变成了一维数组)。注意:在这里一直强调的是多维数组,虽然我们举的例子都是二维数组,但是一定要清楚,Python是有能力并且可以处理多维数组,ndarray中的nd就是n维的意思。

代码如下:

a = np.arange(1,13) #生成一个12个元素一维数组
b = a.reshape(6,2)  #将12个元素一维数组转换为6x2的二维数组
c = b.reshape(3,4)  #将6x2的二维数组转换为3x4的二维数组
print(b)
print()
print(c)

 运行结果如下:

5.newshape参数的特殊用法-1

newshape允许使用-1的特殊参数,表示将剩余元素都分配到那个轴,如(-1,5),在这种情况下,值是根据数组长度和剩余维度推断。

如将上面的代码中c = b.reshape(3,4)改为c = b.reshape(-1,4)或者改为c = b.reshape(3,-1):

b = a.reshape(6,2)  #将12个元素一维数组转换为6x2的二维数组
c = b.reshape(-1,4)  #将6x2的二维数组转换为3x4的二维数组
print(b)
print()
print(c)

 运行结果与上面的结果相同。但是,万万不能改成c = b.reshape(-1,5),这时由于3*4的数组是12个元素,不能被5整除,元素数量不匹配,会造成运行错误。-1参数对于我们正常操作一般意义不大,实际上只有数组重组前后的元素数必须相等才能够正确重组数组。

 6.order参数

也许order参数本身就是Python的一个Bug,或者是一个程序狂人给广大程序员挖下的一个陷阱,幸亏这个参数用途并不大。

order参数允许选择使用‘C’或者‘F’或者‘A’,其中省略order参数时默认使用‘C’排序。关键是一段晦涩的英文解释让大家不知道三个参数的区别(参见《附1:numpy.reshape原始说明文档》中关于order参数选择的描述)。

我们先用例子来测试一下各参数的运行结果:

x = np.arange(6).reshape((3, 2))
c = np.reshape(x, (2, 3), order='C') # C-like index ordering 这是原始文档中的注释
f = np.reshape(x, (2, 3), order='F') # Fortran-like index ordering 这是原始文档中的注释
a = np.reshape(x, (2, 3), order='A') # A没有举例也没有注释
print('x=',x)
print()
print('c=',c)
print()
print('f=',f)
print()
print('a=',a)

 我们看一下运行结果

 当order='C'时,与省略order时相同,是将源数组拉伸成一维数组(0到5的6个自然数)后再重组成(2,3)的数组。

 当order='A'时与order='C'时排列的完全相同。

当order='F'时是怎么排列的?Fortran-like index ordering又是什么鬼?

实际上C-lik index ordering是像C索引那样排序,Fortran-like index ordering是像Fortran索引那样排序,在这里省掉了computer language的描述,是造成大部分人难以理解这里说的是什么。

上述描述确切的翻译过来是像C语言的数组顺序那样排序;像Fortran语言的数组顺序那样排序,这样就很接近答案了。可是又有多少人知道Fortran语言呢?Fortran语言与C语言的数组顺序有什么区别呢?

Fortran语言是一个很古老的编程语言,是IBM公司的约翰·贝克斯(John Backus)于1951年针对汇编语言的缺点研究开发的高级语言,也是世界上第一个计算机高级语言,用于科学和工程计算领域,至今仍然有一些程序员在使用Fortran语言编程,实际上他就像梵文一样是古老而又不可或缺的语言,只是现在已经被边缘化了,连计算机教学中都很少被提到。

Fortran语言的数组与C语言等现在编程语言的排列方式不同,它老人家是按列的顺序排列,而且数组下标是从1开始(C语言的数组下标从0开始,但这与现在讨论的问题无关,在此举例时为了尊敬这个古老的语言才提到此问题),例如一个(3,2)的数组:

在C语言中的索引顺序是从左到右,从上到下: A[0][0], A[0][1], A[1][0], A[1][1], A[2][0], A[2][1]

而在Fortran语言中则是 从上到下,从左到右 : A[1][1], A[2][1], A[3][1], A[1][2], A[2][2], A[3][2]

再次强调:我们在这里看的只是排列顺序,与起始下标无关。

实际上这里的C与F按照Python的惯例应当写成index和columns或者写成axis=0和axis=1。

我们观察一下上面例子中order=‘F’行,可以理解为什么结果是[0 4 3],[2,1,5]了吗?我开始也没有理解,经观察发现,当使用F参数时在拉伸和重组时都要按列进行。

源数组是(3,2)的数组,样式如下:

 首先把数组按列拉伸成如下形式:

 然后再按列重组成(2,3)的数组

最后是选项‘A’,原文说的很啰嗦,它的意思就是按照数据在内存中存储的顺序进行排序。我使用的是windows系统,本身就是使用C语言编写的,肯定会按照C选项排序的,也许其它计算机的A排序会有所不同。

7.完整的例子

x = np.arange(6).reshape((3, 2))
c1 = np.reshape(x, (2, 3), order='C') # C-按行的顺序读取数组,拉伸成一维数组后,再按行的顺序重新分配
c2 = np.reshape(np.ravel(x, order='C'), (2, 3)) # 相当于先拉伸成一维数组,再重组成3x2的数组
f1 = np.reshape(x, (2, 3), order='F') # F-按列的顺序读取数组,拉伸成一维数组后,再按列的顺序重新分配
f2 = np.reshape(np.ravel(x, order='F'), (2, 3), order='F')
a = np.reshape(x, (2, 3), order='A') # A-按内存的顺序读取数组,拉伸成一维数组后,再按内存的顺序重新分配(在此同C)
print('x=',x)
print()
print(np.ravel(x, order='C'))
print('c1=',c1)
print('c2=',c2)
print()
print(np.ravel(x, order='F'))
print('f1=',d)
print('f2=',e)
print()
print('a=',a)

以下是运行结果

8.总结

ndarray.reshape( newshape, order='C')

numpy.reshape(a, newshape, order='C')

newshape:整数或整数元组,如(2,3)。

  1. 新形状应与原始形状兼容(元素数相同)。如果新形状的第一维是元素的总数,则结果将是该长度的一维数组。
  2. 有一个特殊的newshape 是-1,表示将剩余元素都分配到那个轴,如(-1,5),在这种情况下,值是根据数组长度和剩余维度推断。
  3. 注意:重组后的数组元素数必须保证与重组前完全相等,否则报错。

order : 可选值{'C', 'F', 'A'}。

  1. 'C'-使用C语言数组的顺序读取元素(按行的顺序读取数组A[0][0], A[0][1], A[0][2]…. ,C语言数组下标从0开始,但与本话题无关),拉伸成一维数组后再重新按行分配;
  2. 'F'-使用Fortran语言数组的顺序读取元素(按列的顺序读取数组A[1][1], A[2][1], A[3][1]….,Fortran语言数组下标从1开始,但与本话题无关),拉伸成一维数组后再重新按列分配;
  3. “C”和“F”选项不考虑内存的存储顺序,仅以引用索引顺序为准。
  4. ‘A’-按照数据在内存中存储的顺序来拉伸成一维数组后再按内存的顺序重新分配。


附1:numpy.reshape原始说明文档

Help on function reshape in module numpy:

reshape(a, newshape, order='C')
    Gives a new shape to an array without changing its data.
    
    Parameters
    ----------
    a : array_like
        Array to be reshaped.
    newshape : int or tuple of ints
        The new shape should be compatible with the original shape. If
        an integer, then the result will be a 1-D array of that length.
        One shape dimension can be -1. In this case, the value is
        inferred from the length of the array and remaining dimensions.
    order : {'C', 'F', 'A'}, optional
        Read the elements of `a` using this index order, and place the
        elements into the reshaped array using this index order.  'C'
        means to read / write the elements using C-like index order,
        with the last axis index changing fastest, back to the first
        axis index changing slowest. 'F' means to read / write the
        elements using Fortran-like index order, with the first index
        changing fastest, and the last index changing slowest. Note that
        the 'C' and 'F' options take no account of the memory layout of
        the underlying array, and only refer to the order of indexing.
        'A' means to read / write the elements in Fortran-like index
        order if `a` is Fortran *contiguous* in memory, C-like order
        otherwise.
    
    Returns
    -------
    reshaped_array : ndarray
        This will be a new view object if possible; otherwise, it will
        be a copy.  Note there is no guarantee of the *memory layout* (C- or
        Fortran- contiguous) of the returned array.
    
    See Also
    --------
    ndarray.reshape : Equivalent method.
    
    Notes
    -----
    It is not always possible to change the shape of an array without
    copying the data. If you want an error to be raised when the data is copied,
    you should assign the new shape to the shape attribute of the array::        

附2:ndarray.reshape原始说明文档

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

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

Refer to `numpy.reshape` for full documentation.

See Also
--------
numpy.reshape : equivalent function

Notes
-----
Unlike the free function `numpy.reshape`, this method on `ndarray` allows
the elements of the shape parameter to be passed in as separate arguments.
For example, ``a.reshape(10, 11)`` is equivalent to
``a.reshape((10, 11))``.
Type:      builtin_function_or_method

  • 14
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: Pythonreshape函数有三个参数,分别是原数组、新数组的形状和可选的参数order。其原数组是需要进行形状变换的数组,新数组的形状是一个元组,用于指定新数组的形状,可选的参数order用于指定新数组的元素在内存的排列方式。 ### 回答2: Pythonreshape函数是用来改变数组或矩阵的行数和列数的,reshape函数有四个参数,分别是: 1.第一个参数为需要改变形状的数组或矩阵,必选参数。 2.第二个参数为目标行数,可选参数,如果只指定一个参数,则数组会被重塑为1行的矩阵。 3.第三个参数为目标列数,可选参数,如果只指定第二个参数,则数组会被重塑为1列的矩阵。 4.第四个参数为是否保留原数组或矩阵的元素顺序的布尔值参数,可选参数,当取值为True时保留原元素顺序,如果取值为False时,元素会按照行优先的顺序重新排列。 例如,使用reshape对一个2x3的二维数组进行修改: import numpy as np arr = np.array([[1, 2, 3], [4, 5, 6]]) new_arr = arr.reshape(3, 2, False) print(new_arr) 输出: [[1 2] [3 4] [5 6]] 在这个例子,原来的数组有2行3列,而reshape函数将其改变为3行2列的新矩阵,并且保留了原数组的元素顺序。 ### 回答3: Pythonreshape是一种重塑数据的方法,它可以将一个数组或矩阵转换成新的形状。在Pythonreshape有4个参数,分别为rows、cols、layers和order。 其rows代表想要设置的新矩阵的行数,cols代表想要设置的新矩阵的列数,layers代表想要设置的新矩阵的几层,而order则是可选的参数,它指示数组如何在内存表示。如果不指定order,则默认为C(行主序)。 当使用reshape方法时,首先需要确保重新组织后的数组的总元素数量与原数组的总元素数量相等,否则reshape操作将失败。如果总元素数量不同,则需要使用其他操作,如插入或删除元素,才能成功进行reshape操作。 在实际使用reshape方法广泛应用于数据预处理、数据降维、图像处理等领域。它可以灵活地修改矩阵的形状,以便更好地适应各种应用场景。因此,理解pythonreshape参数是非常重要的。通过适当地使用这些参数,可以使reshape操作更加准确、快速和高效。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值