NumPy快速开始(2)

论坛 期权论坛 脚本     
匿名技术用户   2020-12-29 07:37   770   0

接着上一篇文章,接下来开始对其他的一些翻译。

形状操作

改变数组的形状

一个数组由每一个轴中的元素数量给出形状:

>>> import numpy as np
>>> a=np.floor(10*np.random.random((3,4)))  #np.floor表示数据取下,如np.floor(3.4)=3
>>> a
array([[9., 4., 3., 5.],
       [5., 8., 3., 0.],
       [6., 4., 9., 3.]])
>>> a.shape
(3, 4)

一个数组的形状可以通过多种命令改变的。注意接下来的三个命令返回的是修改的数组,并不会改变源数组:

>>> a.ravel()     #平铺操作,类似于上一节的flat
array([9., 4., 3., 5., 5., 8., 3., 0., 6., 4., 9., 3.])
>>> a.reshape(6,2)
array([[9., 4.],
       [3., 5.],
       [5., 8.],
       [3., 0.],
       [6., 4.],
       [9., 3.]])
>>> a.T           # a 的转置
array([[9., 5., 6.],
       [4., 8., 4.],
       [3., 3., 9.],
       [5., 0., 3.]])
>>> a.T.shape
(4, 3)
>>> a.shape
(3, 4)

ravel() 产生的数组中元素的顺序通常是“C风格”,也就是说,最右边的索引“改变最快”,所以[0,0]之后的元素是[0,1] 。如果数组被重新塑造成其他形状,数组又被视为“C-style”。NumPy通常创建按此顺序存储的数组,因此 ravel() 通常不需要复制其参数,但如果数组是通过切片另一个数组或使用不寻常选项创建的,则可能需要复制它。函数ravel()和reshape()也可以通过使用可选参数来指示使用FORTRAN风格的数组,其中最左侧的索引更改速度最快。

reshape 函数返回的是修改的形状,但是 ndarray.resize 返回的是自身。

>>> a
array([[9., 4., 3., 5.],
       [5., 8., 3., 0.],
       [6., 4., 9., 3.]])
>>> a.resize((2,6))
>>> a
array([[9., 4., 3., 5., 5., 8.],
       [3., 0., 6., 4., 9., 3.]])
>>> a.reshape((3,4))
array([[9., 4., 3., 5.],
       [5., 8., 3., 0.],
       [6., 4., 9., 3.]])
>>> a.shape
(2, 6)

如果在 reshape 操作时某一个维度给 -1 ,则其他的维度自动计算。

>>> a.reshape(3,-1)
array([[9., 4., 3., 5.],
       [5., 8., 3., 0.],
       [6., 4., 9., 3.]])

另见:

ndarray.shape, reshape, resize, ravel

将不同的数组堆叠起来

一些数组可以沿着不同的轴堆叠起来:

>>> a=np.floor(10*np.random.random((2,2)))
>>> a
array([[9., 7.],
       [6., 2.]])
>>> b=np.floor(10*np.random.random((2,2)))
>>> b
array([[4., 2.],
       [1., 5.]])
>>> np.vstack((a,b))     #按行进行堆叠
array([[9., 7.],
       [6., 2.],
       [4., 2.],
       [1., 5.]])
>>> np.hstack((a,b))      #按列进行堆叠
array([[9., 7., 4., 2.],
       [6., 2., 1., 5.]])

函数 column_stack 按列堆叠一维数组维2D数组。等价于仅用 hstack

>>> from numpy import newaxis
>>> np.column_stack((a,b))     # with 2D arrays
array([[ 8.,  8.,  1.,  8.],
       [ 0.,  0.,  0.,  4.]])
>>> a = np.array([4.,2.])
>>> b = np.array([3.,8.])
>>> np.column_stack((a,b))     # returns a 2D array
array([[ 4., 3.],
       [ 2., 8.]])
>>> np.hstack((a,b))           # the result is different
array([ 4., 2., 3., 8.])
>>> a[:,newaxis]               # this allows to have a 2D columns vector
array([[ 4.],
       [ 2.]])
>>> np.column_stack((a[:,newaxis],b[:,newaxis]))
array([[ 4.,  3.],
       [ 2.,  8.]])
>>> np.hstack((a[:,newaxis],b[:,newaxis]))   # the result is the same
array([[ 4.,  3.],
       [ 2.,  8.]])

另一方面,对于任何输入数组,函数 row_stack 相当于 vstack。一般来说,对于具有两个以上维度的数组,hstack 沿第二轴堆叠,vstack 沿第一轴堆叠,concatenate 允许一个可选参数,给出串接应该发生的轴。

注意:在复杂情况下,r_c_ 可用于通过沿一个轴叠加数字来创建数组。它们允许使用范围字面量(“:”)

>>> np.r_[1:4,0,4]
array([1, 2, 3, 0, 4])

当以数组作为参数使用时,r_c_ 类似于其默认行为中的 vstackhstack ,但是允许一个可选参数给出要沿其连接的轴的编号。

另见:

hstack, vstack, column_stack, concatenate, c_, r_

将一个数组分成几个较小的数组

使用 hsplit ,可以沿其水平轴拆分数组,通过指定要返回的均匀划分的数组数量,或通过指定要在其后进行划分的列:

>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[ 9.,  5.,  6.,  3.,  6.,  8.,  0.,  7.,  9.,  7.,  2.,  7.],
       [ 1.,  4.,  9.,  2.,  2.,  1.,  0.,  6.,  2.,  2.,  4.,  0.]])
>>> np.hsplit(a,3)   # Split a into 3
[array([[ 9.,  5.,  6.,  3.],
       [ 1.,  4.,  9.,  2.]]), array([[ 6.,  8.,  0.,  7.],
       [ 2.,  1.,  0.,  6.]]), array([[ 9.,  7.,  2.,  7.],
       [ 2.,  2.,  4.,  0.]])]
>>> np.hsplit(a,(3,4))   # Split a after the third and the fourth column
[array([[ 9.,  5.,  6.],
       [ 1.,  4.,  9.]]), array([[ 3.],
       [ 2.]]), array([[ 6.,  8.,  0.,  7.,  9.,  7.,  2.,  7.],
       [ 2.,  1.,  0.,  6.,  2.,  2.,  4.,  0.]])]

vsplit 沿纵轴分割,并且 array_split 允许指定沿哪个轴分割。

拷贝和视图

当操作和计算数组时,数据有时复制为一个新的数组,有时并不是。这对于新手来说是一个困惑。下面有三种情况:

完全不拷贝

简单拷贝不会创建数组对象或其数据的拷贝。

>>> a=np.arange(12)
>>> b=a            #没有新的目标被创建
>>> b is a          #a 和 b 公用内存中的一个目标,只是名字不同而已
True
>>> b.shape=3,4        #改变 b 的形状,a 的形状也会改变
>>> a.shape
(3, 4)

Python将可变对象作为引用传递,所以函数调用不会复制。

>>> def f(x):
 print(id(x))

 
>>> id(a)     # id 是一个识别目标的函数
2378141967984
>>> f(a)
2378141967984
>>> 

视图或者浅拷贝

不同的数组目标可以共享相同的数据。 view 方法创建一个新的数组目标,可以查看相同的数据。

>>> c=a.view()
>>> c is a
False
>>> c.base is a                        # c is a view of the data owned by a
True
>>> c.flags.owndata
False
>>> 
>>> c.shape=2,6                     # a 的形状不会因为c的改变而变化
>>> a.shape
(3, 4)
>>> c[0,4]
4
>>> c[0,4]=1234                    # c 的数据改变会让 a 的数据变化
>>> a
array([[   0,    1,    2,    3],
       [1234,    5,    6,    7],
       [   8,    9,   10,   11]])

对数组切片返回一个视图:

>>> s=a[:,1:3]
>>> s
array([[ 1,  2],
       [ 5,  6],
       [ 9, 10]])
>>> s[:]=10
>>> s
array([[10, 10],
       [10, 10],
       [10, 10]])
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

深拷贝

copy 方法完全拷贝源数据的数组和数据,同时也会在内存中开辟一个新地方来存储。

>>> d=a.copy()
>>> d is a
False
>>> d.base is a
False
>>> d[0,0]
0
>>> d[0,0]=999
>>> a
array([[   0,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])
>>> d
array([[ 999,   10,   10,    3],
       [1234,   10,   10,    7],
       [   8,   10,   10,   11]])

函数和方法总结

这里列出了一些根据类别排列的有用的NumPy函数和方法名称。完整列表见Routines

创建数组

arange, array, copy, empty, empty_like, eye, fromfile, fromfunction, identity, linspace, logspace, mgrid, ogrid, ones, ones_like, r, zeros, zeros_like

转换

ndarray.astype, atleast_1d, atleast_2d, atleast_3d, mat

手法

array_split, column_stack, concatenate, diagonal, dsplit, dstack, hsplit, hstack, ndarray.item, newaxis, ravel, repeat, reshape, resize, squeeze, swapaxes, take, transpose, vsplit, vstack

问题

all, any, nonzero, where

顺序

argmax, argmin, argsort, max, min, ptp, searchsorted, sort

操作

choose, compress, cumprod, cumsum, inner, ndarray.fill, imag, prod, put, putmask, real, sum

基本统计

cov, mean, std, var

基本线性代数

cross, dot, outer, linalg.svd, vdot

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP