数据分析----numpy快速入门

简介: numpy快速入门,包含如何numpy中矩阵属性、创建矩阵方法、打印矩阵、矩阵的基本运算、矩阵的通用函数、矩阵的索引、切片和遍历、矩阵的堆叠与拆分、矩阵拷贝、矩阵索引高级用法等

一、numpy的安装

若直接使用系统的python环境,则使用如下命令安装

pip install numpy

若使用pipenv工具创建的虚拟环境,则使用如下命令:

pipenv install numpy

二、Numpy中矩阵array的基本属性

  • ndim:维数

比如3x4的矩阵,它的ndim为2

  • shape:表示几行几列,用元组表示

比如3x4矩阵,它的shape为(3,4)

  • size: 元素的总的数量

比如3x4的矩阵,它的size为12

  • dtype:元素的类型

可以直接使用python的中类型,numpy也提供了一些类型比如numpy.int32, numpy.int16, numpy.float64 等

  • itemsize: 元素的大小

每个元素占用的内存,单位是字节,比如类型时int64,则itemsize为8个字节,相当于是dtype.itemsize

实例如下,其中arr=np.arange(12).reshape((3,4))是用于创建一个3x4的矩阵,元素是0-11,后面会继续详解如何创建矩阵的,这里是为了演示矩阵的属性

>>> import numpy as np
>>> arr=np.arange(12).reshape((3,4))
>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> arr.ndim
2
>>> arr.shape
(3, 4)
>>> arr.dtype
dtype('int32')
>>> arr.dtype.name
'int32'
>>> arr.size
12
>>> arr.itemsize
4
>>> type(arr)
<class 'numpy.ndarray'>
>>>

三、创建矩阵

3.1 通过使用Python的list或者tuple来创建矩阵

如下,分别使用一维列表,一维元组,二维列表,二维元组创建矩阵

>>> import numpy as np
>>> arr=np.array([1,2,3])
>>> arr
array([1, 2, 3])
>>> arr=np.array((1,2,3))
>>> arr
array([1, 2, 3])
>>> arr=np.array([[1,2,3],[4,5,6]])
>>> arr
array([[1, 2, 3],
       [4, 5, 6]])
>>> arr=np.array(((1,2,3),(4,5,6)))
>>> arr
array([[1, 2, 3],
       [4, 5, 6]])
>>>

这里需要注意一下,np.array的参数是列表或元素,如果直接给定几个元素时不可以的,如下是一个初学者常见的错误

>>> import numpy as np
>>> arr=np.array(1,2,3,4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: array() takes from 1 to 2 positional arguments but 4 were given

正确的应该如下:

>>> import numpy as np
>>> arr=np.array([1,2,3,4])
>>> arr
array([1, 2, 3, 4])

此外创建矩阵的时候,还可以指定数据的类型,下面先看一下不指定数据类型时,默认的数据类型,当然这个是会和计算机平台有关的,如下,默认情况下是32位的int类型

>>> import numpy as np
>>> arr=np.array([1,2,3])
>>> arr
array([1, 2, 3])
>>> arr.dtype
dtype('int32')
>>>

如下,即可通过dtype参数指定矩阵元素的类型

>>> import numpy as np
>>> arr=np.array([1,2,3],dtype=np.int64)
>>> arr
array([1, 2, 3], dtype=int64)
>>> arr.dtype
dtype('int64')
>>>

3.2 通过常用的基本函数创建矩阵

常用的函数如下

  • zeros:创建所有元素均为0的矩阵
  • ones:创建所有元素都为1的矩阵
  • empty:创建元素随机的矩阵,默认情况下empty函数创建的元素类型为float64,当然可以也可以通过dtype参数指定类型。
  • arange:类似于python中range的函数,可以通过指定初始值和结束值以及步长来生成等差数列的,当然可以通过reshape函数对生成的一维等差数列转换为多维矩阵。
  • linspace:通过指定起始值和结束值以及生成的数字的个数,然后自动进行等差分割,同样可以通过reshape函数对生成的一维列表转换为多维矩阵

举例如下:

>>> import numpy as np
>>> arr=np.zeros((3,4))
>>> arr
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
>>> arr=np.ones((3,4))
>>> arr
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
>>> arr=np.empty((3,4))
>>> arr
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
>>> arr=np.empty((3,4),dtype=np.int32)
>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> arr=np.arange(0,12,1).reshape((3,4))
>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> arr=np.arange(0,24,2).reshape((3,4))
>>> arr
array([[ 0,  2,  4,  6],
       [ 8, 10, 12, 14],
       [16, 18, 20, 22]])
>>> arr=np.linspace(1,100,12).reshape((3,4))
>>> arr
array([[  1.,  10.,  19.,  28.],
       [ 37.,  46.,  55.,  64.],
       [ 73.,  82.,  91., 100.]])
>>>

四、打印矩阵

numpy在打印多维矩阵的时候,会遵循如下布局

  • 最后一个维度从左到右打印
  • 倒数第二个维度从上到下打印
  • 剩下的都是从上到下打印,并且每个维度之间使用一个空行分隔

如下为分表打印一维、二维、三维矩阵

>>> import numpy as np
>>> arr=np.arange(6)
>>> print(arr)
[0 1 2 3 4 5]
>>> b=np.arange(12).reshape((3,4))
>>> print(b)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
>>> c=np.arange(24).reshape((2,3,4))
>>> print(c)
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]]
>>>

如果矩阵元素特别多,则numpy会只个保留角落的部分,中间的则使用 ... 代替,如下:

>>> import numpy as np
>>> arr=np.arange(10000)
>>> print(arr)
[   0    1    2 ... 9997 9998 9999]
>>> arr=np.arange(10000).reshape((100,100))
>>> print(arr)
[[   0    1    2 ...   97   98   99]
 [ 100  101  102 ...  197  198  199]
 [ 200  201  202 ...  297  298  299]
 ...
 [9700 9701 9702 ... 9797 9798 9799]
 [9800 9801 9802 ... 9897 9898 9899]
 [9900 9901 9902 ... 9997 9998 9999]]
>>>

当然如果就是要打印全部元素也是可以设置,通过使用set_printoptions来控制

np.set_printoptions(threshold=sys.maxsize)

五、基本运算

基本的加减乘除乘方就是矩阵的元素与元素之间进行加减乘除乘方,如下

>>> import numpy as np
>>> a=np.array([1,2,3,4])
>>> b=np.arange(4)
>>> a
array([1, 2, 3, 4])
>>> b
array([0, 1, 2, 3])
>>> a+b
array([1, 3, 5, 7])
>>> a-b
array([1, 1, 1, 1])
>>> a*b
array([ 0,  2,  6, 12])
>>> b/a
array([0.        , 0.5       , 0.66666667, 0.75      ])
>>> a>0
array([ True,  True,  True,  True])
>>> a**2
array([ 1,  4,  9, 16])
>>> b>2
array([False, False, False,  True])
>>> np.sin(a)
array([ 0.84147098,  0.90929743,  0.14112001, -0.7568025 ])
>>> np.cos(a)
array([ 0.54030231, -0.41614684, -0.9899925 , -0.65364362])
>>> np.tan(a)
array([ 1.55740772, -2.18503986, -0.14254654,  1.15782128])

矩阵的点乘使用dot或者使用@符号,如下:

>>> a=np.array([[1,1],[0,1]])
>>> b=np.array([[2,0],[3,4]])
>>> a
array([[1, 1],
       [0, 1]])
>>> b
array([[2, 0],
       [3, 4]])
>>> a*b
array([[2, 0],
       [0, 4]])
>>> a@b
array([[5, 4],
       [3, 4]])
>>> a.dot(b)
array([[5, 4],
       [3, 4]])
>>> np.dot(a,b)
array([[5, 4],
       [3, 4]])
>>>

有些运算符比如 +=或*=,会直接对已有的矩阵做处理而不是创建一个新的矩阵,如下,其中 np.random.default_rng(1)是默认的随机数生成器

>>> import numpy as np
>>> rng=np.random.default_rng(1)
>>> a=np.ones((2,3),dtype=np.int32)
>>> b=rng.random((2,3))
>>> a
array([[1, 1, 1],
       [1, 1, 1]])
>>> b
array([[0.51182162, 0.9504637 , 0.14415961],
       [0.94864945, 0.31183145, 0.42332645]])
>>> a*=3
>>> a
array([[3, 3, 3],
       [3, 3, 3]])
>>> b+=a
>>> b
array([[3.51182162, 3.9504637 , 3.14415961],
       [3.94864945, 3.31183145, 3.42332645]])
>>> a+=b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
numpy.core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'add' output from dtype('float64') to dtype('int32') with casting rule 'same_kind'
>>>

当运算中涉及多种类型时,结果会按照向上转换的原则,如下:

>>> import numpy as np
>>> a=np.ones(3,dtype=np.int32)
>>> b=np.linspace(0,np.pi,3)
>>> a
array([1, 1, 1])
>>> b
array([0.        , 1.57079633, 3.14159265])
>>> c=a+b
>>> c
array([1.        , 2.57079633, 4.14159265])
>>> b.dtype
dtype('float64')
>>> c.dtype
dtype('float64')
>>> d=np.exp(c*1j)
>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
       -0.54030231-0.84147098j])
>>> d.dtype
dtype('complex128')
>>>

计算矩阵所有元素的和、最大值、最小值函数,即sum、max和min,如下:

>>> import numpy as np
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> a.sum()
66
>>> np.sum(a)
66
>>> a.max()
11
>>> np.max(a)
11
>>> a.min()
0
>>> np.min(a)
0
>>>

通过axis参数可以按行或按列计算元素和、最大值和最小值,当axis=0时,表示按列,当axis=1时,表示按行,如下

>>> import numpy as np
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> a.sum(axis=0)
array([12, 15, 18, 21])
>>> np.sum(a,axis=0)
array([12, 15, 18, 21])
>>> a.sum(axis=1)
array([ 6, 22, 38])
>>> np.sum(a,axis=1)
array([ 6, 22, 38])
>>> a.max(axis=0)
array([ 8,  9, 10, 11])
>>> np.max(a,axis=0)
array([ 8,  9, 10, 11])
>>> a.max(axis=1)
array([ 3,  7, 11])
>>> np.max(a,axis=1)
array([ 3,  7, 11])
>>> a.min(axis=0)
array([0, 1, 2, 3])
>>> np.min(a,axis=0)
array([0, 1, 2, 3])
>>> a.min(axis=1)
array([0, 4, 8])
>>> np.min(a,axis=1)
array([0, 4, 8])
>>>

六、通用函数

常用的通用函数如下:

  • sin
  • cos
  • exp
  • sqrt
  • add
  • all
  • any
  • apply_along_axis
  • argmax
  • argmin
  • argsort
  • average
  • bincount
  • ceil
  • clip
  • conj
  • corrcoef
  • cov
  • cross
  • cumprod
  • cumsum
  • diff
  • dot
  • floor
  • inner
  • invert
  • lexsort
  • max
  • maximum
  • mean
  • median
  • min
  • minimum
  • nonzero
  • outer
  • prod
  • re
  • round
  • sort
  • std
  • sum
  • trace
  • transpose
  • var
  • vdot
  • vectorize
  • where

举例如下:

>>> import numpy as np
>>> a=np.arange(3)
>>> a
array([0, 1, 2])
>>> np.exp(a)
array([1.        , 2.71828183, 7.3890561 ])
>>> np.sqrt(a)
array([0.        , 1.        , 1.41421356])
>>> b=np.array([4,5,6])
>>> b
array([4, 5, 6])
>>> np.add(a,b)
array([4, 6, 8])
>>>

七、索引、切片和迭代

7.1 一维矩阵的索引、切片和迭代使用方法

一维矩阵的索引、切片和迭代使用方法像python中列表的索引、切片、迭代一样,如下:

>>> import numpy as np
>>> a=np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[2]
2
>>> a[2:5]
array([2, 3, 4])
>>> a[:6:2]
array([0, 2, 4])
>>> a[::-1]
array([9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
>>> for i in a:
...    print(i)
...
0
1
2
3
4
5
6
7
8
9
>>>

7.2 多维矩阵的索引、切片和迭代

多维矩阵的索引、切片和迭代,主要区别就是每个维度使用一个索引,中间用逗号隔开,如下:

>>> import numpy as np
>>> a=np.arange(20).reshape((5,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19]])
>>> a[2,3]
11
>>> a[0:4,1]
array([ 1,  5,  9, 13])
>>> a[:,1]
array([ 1,  5,  9, 13, 17])
>>> a[1:3:,:]
array([[ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> for elem in a[:,1]:
...     print(elem)
...
1
5
9
13
17
>>> for elem in a[:,:]:
...     print(elem)
...
[0 1 2 3]
[4 5 6 7]
[ 8  9 10 11]
[12 13 14 15]
[16 17 18 19]
>>>

当提供的索引的数量少于矩阵的维数,则后续默认为:,如下a[2],就相当于是a[2,:]

>>> import numpy as np
>>> a=np.arange(20).reshape((4,5))
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
>>> a[2]
array([10, 11, 12, 13, 14])
>>>

当多维矩阵时,可以通过使用三个点来代替其他维数,比如如下假设a是一个五维矩阵,则:

  • a[1,2,...]就相当于a[1,2,:,:,:]
  • a[...,3]就相当于a[:,:,:,:,3]
  • a[4,...,5,:]就相当于a[4,:,:,5,:]

如下

>>> import numpy as np
>>> a=np.arange(24).reshape((2,3,4))
>>> a
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
>>> a[1,...]
array([[12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])
>>> a[1,:,:]
array([[12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])
>>> a[...,2]
array([[ 2,  6, 10],
       [14, 18, 22]])
>>> a[:,:,2]
array([[ 2,  6, 10],
       [14, 18, 22]])
>>>

当对多维矩阵进行遍历的时候通常按照第一个维度进行遍历,当希望对每个元素进行遍历的时候,可以使用flat属性,如下

>>> import numpy as np
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> for elem in a:
...     print(elem)
...
[0 1 2 3]
[4 5 6 7]
[ 8  9 10 11]
>>> for elem in a.flat:
...     print(elem)
...
0
1
2
3
4
5
6
7
8
9
10
11
>>>

八、对矩阵shape的操作

对于矩阵以下三个方法不会改变矩阵的shape原有的值

  • ravel:将矩阵展开为一维矩阵
  • T:矩阵转秩
  • reshape:重新调整shape,但不会修改原有shape

如下

>>> import numpy as np
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b=a.ravel()
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
>>> c=a.reshape(6,2)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> c
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11]])
>>> d=a.T
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> d
array([[ 0,  4,  8],
       [ 1,  5,  9],
       [ 2,  6, 10],
       [ 3,  7, 11]])
>>> a.shape
(3, 4)
>>> a.T.shape
(4, 3)
>>> e=a.reshape((6,2))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> e
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11]])
>>>

若想对原有矩阵的shape进行调整,可以使用resize函数,如下,可以发现resize函数是直接对原来的矩阵进行调整,同时没有返回值,即在下面的例子中b为空

>>> import numpy as np
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b=a.resize(6,2)
>>> a
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11]])
>>> b
>>>

再使用reshape函数的时候,如果某一个维度设置为-1,则表示此维度自动计算,如下

>>> import numpy as np
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b=a.reshape(6,-1)
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11]])
>>>

九、不同矩阵之间的堆叠

不同矩阵之间的水平堆叠和垂直堆叠,如下

>>> import numpy as np
>>> a=np.arange(4).reshape((2,2))
>>> b=np.arange(4,8).reshape((2,2))
>>> a
array([[0, 1],
       [2, 3]])
>>> b
array([[4, 5],
       [6, 7]])
>>> np.vstack((a,b))
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])
>>> np.hstack((a,b))
array([[0, 1, 4, 5],
       [2, 3, 6, 7]])
>>>

column_stack只有在二维矩阵时才相当于hstack,而row_stack就是vstack的别名,如下

>>> import numpy as np
>>> a=np.arange(3)
>>> b=np.arange(3,6)
>>> a
array([0, 1, 2])
>>> b
array([3, 4, 5])
>>> np.column_stack((a,b))
array([[0, 3],
       [1, 4],
       [2, 5]])
>>> np.hstack((a,b))
array([0, 1, 2, 3, 4, 5])
>>> np.row_stack((a,b))
array([[0, 1, 2],
       [3, 4, 5]])
>>> np.vstack((a,b))
array([[0, 1, 2],
       [3, 4, 5]])
>>> a=np.arange(4).reshape((2,2))
>>> b=np.arange(4,8).reshape((2,2))
>>> a
array([[0, 1],
       [2, 3]])
>>> b
array([[4, 5],
       [6, 7]])
>>> np.column_stack((a,b))
array([[0, 1, 4, 5],
       [2, 3, 6, 7]])
>>> np.hstack((a,b))
array([[0, 1, 4, 5],
       [2, 3, 6, 7]])
>>> np.row_stack((a,b))
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])
>>> np.vstack((a,b))
array([[0, 1],
       [2, 3],
       [4, 5],
       [6, 7]])
>>> np.column_stack is np.hstack
False
>>> np.row_stack is np.vstack
True
>>>

十、通过newaxis为现有矩阵增加一个维度

简单来说就是将newaxis参数放在哪个位置,哪个位置对应的维度就设置为1,举例如下

>>> import numpy as np
>>> a=np.array([1,2,3,4])
>>> a
array([1, 2, 3, 4])
>>> a.shape
(4,)
>>> b=a[:,np.newaxis]
>>> b
array([[1],
       [2],
       [3],
       [4]])
>>> b.shape
(4, 1)
>>> c=a[np.newaxis,:]
>>> c
array([[1, 2, 3, 4]])
>>> c.shape
(1, 4)
>>>

十一、将矩阵切割为许多更小的矩阵

分割矩阵可以使用hsplit和vsplit,参数可以是一个数字,表示将矩阵按照列或者行分为n个小矩阵,也可以是一个元素,表示在元组中每一个数字对应的列或行之后进行分割,如下

>>> import numpy as np
>>> a=np.arange(24).reshape((4,6))
>>> a
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])
>>> np.hsplit(a,3)  # 表示将a按照列分为3个小矩阵
[array([[ 0,  1],
       [ 6,  7],
       [12, 13],
       [18, 19]]), array([[ 2,  3],
       [ 8,  9],
       [14, 15],
       [20, 21]]), array([[ 4,  5],
       [10, 11],
       [16, 17],
       [22, 23]])]
>>> np.vsplit(a,2) # 表示将a按照行分为2个小矩阵
[array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]]), array([[12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])]
>>> np.hsplit(a,(2,4)) # 表示将a按照列在第2列和第4列后面分割
[array([[ 0,  1],
       [ 6,  7],
       [12, 13],
       [18, 19]]), array([[ 2,  3],
       [ 8,  9],
       [14, 15],
       [20, 21]]), array([[ 4,  5],
       [10, 11],
       [16, 17],
       [22, 23]])]
>>> np.vsplit(a,(1,3)) # 表示将a按照行在第一行和第三行后面分割
[array([[0, 1, 2, 3, 4, 5]]), array([[ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17]]), array([[18, 19, 20, 21, 22, 23]])]
>>>

十二、拷贝和视图

12.1 没有拷贝发生场景

当直接赋值或者是在函数中传递对象,都不会发生拷贝的现象,函数传递参数因为在python中传递的是对象的引用,所以不会发生拷贝,如下

>>> import numpy as mp
>>> a=np.array([1,2,3,4])
>>> b=a
>>> a
array([1, 2, 3, 4])
>>> b
array([1, 2, 3, 4])
>>> b is a
True
>>> def f(x):
...     print(id(x))
...
>>> id(a)
2211569938384
>>> f(a)
2211569938384
>>>

12.2 视图或浅拷贝

通过view函数创建的视图实质上是一个浅拷贝,对拷贝后的对象进行resize不会影响源对象,但是修改值的操作会让源矩阵对应的值同步修改,此外切片本质上也是产生一个新的视图,如下

>>> import numpy as np
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b=a.view()
>>> b
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> id(a)
2211558280336
>>> id(b)
2211569938192
>>> b is a
False
>>> b.base is a
False
>>> b.flags.owndata
False
>>> b.resize((2,6))
>>> b
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b[0,0]=100
>>> b
array([[100,   1,   2,   3,   4,   5],
       [  6,   7,   8,   9,  10,  11]])
>>> a
array([[100,   1,   2,   3],
       [  4,   5,   6,   7],
       [  8,   9,  10,  11]])
>>> c=a[:,0:2]
>>> c
array([[100,   1],
       [  4,   5],
       [  8,   9]])
>>> c.flags.owndata
False
>>> c[0,0]=10000
>>> c
array([[10000,     1],
       [    4,     5],
       [    8,     9]])
>>> a
array([[10000,     1,     2,     3],
       [    4,     5,     6,     7],
       [    8,     9,    10,    11]])
>>> b
array([[10000,     1,     2,     3,     4,     5],
       [    6,     7,     8,     9,    10,    11]])
>>>

12.3 深拷贝

通过copy函数创建的对象为深拷贝,即对新产生的对象修改值等操作不会影响源矩阵,如下

>>> import numpy as np
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b=a.copy()
>>> b
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b.base is a
False
>>> b[0,0]=100
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b
array([[100,   1,   2,   3],
       [  4,   5,   6,   7],
       [  8,   9,  10,  11]])
>>>

十三、索引的高级用法

索引还可以是列表,这样可以一次取出多个数据,如下

>>> import numpy as np
>>> arr=np.arange(10,20)
>>> arr
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>>> index=np.array([1,1,3,7,4])
>>> index
array([1, 1, 3, 7, 4])
>>> arr[index]
array([11, 11, 13, 17, 14])
>>> index=np.array([[1,2,3],[4,5,6],[3,4,7]])
>>> index
array([[1, 2, 3],
       [4, 5, 6],
       [3, 4, 7]])
>>> arr[index]
array([[11, 12, 13],
       [14, 15, 16],
       [13, 14, 17]])
>>>

当矩阵为二维数据时,索引的矩阵中元素代表的是每一行,比如如下

>>> import numpy as np
>>> arr=np.arange(10,22).reshape((3,4))
>>> arr
array([[10, 11, 12, 13],
       [14, 15, 16, 17],
       [18, 19, 20, 21]])
>>> index=np.array([0,1,0,2])
>>> arr[index]
array([[10, 11, 12, 13],
       [14, 15, 16, 17],
       [10, 11, 12, 13],
       [18, 19, 20, 21]])
>>> index=np.array([[0,1,1,0],[1,2,2,1]])
>>> index
array([[0, 1, 1, 0],
       [1, 2, 2, 1]])
>>> arr[index]
array([[[10, 11, 12, 13],
        [14, 15, 16, 17],
        [14, 15, 16, 17],
        [10, 11, 12, 13]],

       [[14, 15, 16, 17],
        [18, 19, 20, 21],
        [18, 19, 20, 21],
        [14, 15, 16, 17]]])
>>>

此外,当源矩阵为多维矩阵,可以通过在索引时使用两个索引矩阵来达到取指定位置的一个数,此时此两个索引矩阵需要拥有相同的shape,如下

>>> import numpy as np
>>> arr=np.arange(10,22).reshape((3,4))
>>> arr
array([[10, 11, 12, 13],
       [14, 15, 16, 17],
       [18, 19, 20, 21]])
>>> i=np.array([[0,1],[1,2]])
>>> j=np.array([[2,1],[3,3]])
>>> i
array([[0, 1],
       [1, 2]])
>>> j
array([[2, 1],
       [3, 3]])
>>> arr[i,j]
array([[12, 15],
       [17, 21]])
>>> arr[i,2]
array([[12, 16],
       [16, 20]])
>>> arr[:,j]
array([[[12, 11],
        [13, 13]],

       [[16, 15],
        [17, 17]],

       [[20, 19],
        [21, 21]]])
>>>

可以利用布尔矩阵为矩阵赋值,如下

>>> import numpy as np
>>> a=np.arange(12).reshape((3,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> b=a>4
>>> b
array([[False, False, False, False],
       [False,  True,  True,  True],
       [ True,  True,  True,  True]])
>>> a[b]
array([ 5,  6,  7,  8,  9, 10, 11])
>>> a[b]=0
>>> a
array([[0, 1, 2, 3],
       [4, 0, 0, 0],
       [0, 0, 0, 0]])
>>>

十四、根据两个数组产生笛卡尔积

使用np.ix_()可以根据输入两个数组产生笛卡尔积的映射关系,如下,其中np.ix_([0,1,2,3],[0,1,2])会产生(0,0),(0,1),(0,2),(1,0,(1,1,(1,2),(2,0),(2,1),(2,2),然后对矩阵取索引,因此得到期望的结果如下

>>> import numpy as np
>>> index=np.ix_([0,1,2,3],[0,1,2])
>>> index
(array([[0],
       [1],
       [2],
       [3]]), array([[0, 1, 2]]))
>>> arr=np.arange(24).reshape((4,6))
>>> arr[index]
array([[ 0,  1,  2],
       [ 6,  7,  8],
       [12, 13, 14],
       [18, 19, 20]])
>>> arr
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])
>>>
目录
相关文章
|
11天前
|
机器学习/深度学习 数据采集 数据挖掘
解锁 Python 数据分析新境界:Pandas 与 NumPy 高级技巧深度剖析
Pandas 和 NumPy 是 Python 中不可或缺的数据处理和分析工具。本文通过实际案例深入剖析了 Pandas 的数据清洗、NumPy 的数组运算、结合两者进行数据分析和特征工程,以及 Pandas 的时间序列处理功能。这些高级技巧能够帮助我们更高效、准确地处理和分析数据,为决策提供支持。
27 2
|
1月前
|
机器学习/深度学习 数据采集 算法
探索Python科学计算的边界:NumPy、Pandas与SciPy在大规模数据分析中的高级应用
【10月更文挑战第5天】随着数据科学和机器学习领域的快速发展,处理大规模数据集的能力变得至关重要。Python凭借其强大的生态系统,尤其是NumPy、Pandas和SciPy等库的支持,在这个领域占据了重要地位。本文将深入探讨这些库如何帮助科学家和工程师高效地进行数据分析,并通过实际案例来展示它们的一些高级应用。
49 0
探索Python科学计算的边界:NumPy、Pandas与SciPy在大规模数据分析中的高级应用
|
1月前
|
数据采集 数据挖掘 API
Python数据分析加速器:深度挖掘Pandas与NumPy的高级功能
在Python数据分析的世界里,Pandas和NumPy无疑是两颗璀璨的明星,它们为数据科学家和工程师提供了强大而灵活的工具集,用于处理、分析和探索数据。今天,我们将一起深入探索这两个库的高级功能,看看它们如何成为数据分析的加速器。
40 1
|
1月前
|
数据挖掘 索引 Python
Python数据分析篇--NumPy--进阶
Python数据分析篇--NumPy--进阶
16 0
|
1月前
|
数据挖掘 索引 Python
Python数据分析篇--NumPy--入门
Python数据分析篇--NumPy--入门
33 0
|
3月前
|
索引 Python
NumPy 快速入门:数组操作基础
【8月更文第30天】NumPy 是 Python 中一个非常重要的科学计算库,它提供了高性能的多维数组对象以及用于操作这些数组的工具。NumPy 数组(也称为 `ndarray`)是 NumPy 库的核心,它比 Python 内置的列表类型更高效,特别是在处理大型数据集时。本文将介绍 NumPy 数组的基本概念、创建方法以及一些常用的数组操作。
44 2
|
3月前
|
数据采集 数据挖掘 数据处理
Python数据分析:Numpy、Pandas高级
在上一篇博文中,我们介绍了Python数据分析中NumPy和Pandas的基础知识。本文将深入探讨NumPy和Pandas的高级功能,并通过一个综合详细的例子展示这些高级功能的应用。
|
3月前
|
数据采集 数据挖掘 数据处理
Python数据分析:Numpy、Pandas基础
本文详细介绍了 Python 中两个重要的数据分析库 NumPy 和 Pandas 的基础知识,并通过一个综合的示例展示了如何使用这些库进行数据处理和分析。希望通过本篇博文,能更好地理解和掌握 NumPy 和 Pandas 的基本用法,为后续的数据分析工作打下坚实的基础。
|
4月前
|
数据采集 数据可视化 数据挖掘
数据分析入门:用Python和Numpy探索音乐流行趋势
数据分析入门:用Python和Numpy探索音乐流行趋势
|
4月前
|
数据采集 数据挖掘 数据处理
Python数据分析加速器:深度挖掘Pandas与NumPy的高级功能
【7月更文挑战第14天】Python的Pandas和NumPy库是数据分析的核心工具。Pandas以其高效的数据处理能力,如分组操作和自定义函数应用,简化了数据清洗和转换。NumPy则以其多维数组和广播机制实现快速数值计算。两者协同工作,如在DataFrame与NumPy数组间转换进行预处理,提升了数据分析的效率和精度。掌握这两者的高级功能是提升数据科学技能的关键。**
45 0