【NumPy 数组副本 vs 视图、NumPy 数组形状、重塑、迭代】

简介: 【NumPy 数组副本 vs 视图、NumPy 数组形状、重塑、迭代】

NumPy 数组副本 vs 视图

副本和视图之间的区别

副本和数组视图之间的主要区别在于副本是一个新数组,而这个视图只是原始数组的视图。

副本拥有数据,对副本所做的任何更改都不会影响原始数组,对原始数组所做的任何更改也不会影响副本。

视图不拥有数据,对视图所做的任何更改都会影响原始数组,而对原始数组所做的任何更改都会影响视图。

副本

实例:

进行复制,更改原始数组并显示两个数组:

import numpy as np
arr = np.array([1, 2, 3, 4, 5])
x = arr.copy()
arr[0] = 61
print(arr) 
print(x)

该副本不应受到对原始数组所做更改的影响。

视图:

实例

创建视图,更改原始数组,然后显示两个数组:

import numpy as np
arr = np.array([1, 2, 3, 4, 5])
x = arr.view()
arr[0] = 61
print(arr) 
print(x)

视图应该受到对原始数组所做更改的影响。

在视图中进行更改:

实例

创建视图,更改视图,并显示两个数组:

import numpy as np
arr = np.array([1, 2, 3, 4, 5])
x = arr.view()
x[0] = 31
print(arr) 
print(x)

原始数组应该受到对视图所做更改的影响。

检查数组是否拥有数据

如上所述,副本拥有数据,而视图不拥有数据,但是我们如何检查呢?

每个 NumPy 数组都有一个属性 base,如果该数组拥有数据,则这个 base 属性返回 None。

否则,base 属性将引用原始对象。

实例

打印 base 属性的值以检查数组是否拥有自己的数据:

import numpy as np
arr = np.array([1, 2, 3, 4, 5])
x = arr.copy()
y = arr.view()
print(x.base)
print(y.base)

副本返回 None。

视图返回原始数组。

NumPy 数组形状

数组的形状是每个维中元素的数量。

获取数组的形状

NumPy 数组有一个名为 shape 的属性,该属性返回一个元组,每个索引具有相应元素的数量。

实例

打印 2-D 数组的形状:

import numpy as np
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
print(arr.shape)

上面的例子返回 (2, 4),这意味着该数组有 2 个维,每个维有 4 个元素。

实例

利用 ndmin 使用值 1,2,3,4 的向量创建有 5 个维度的数组,并验证最后一个维度的值为 4:

import numpy as np
arr = np.array([1, 2, 3, 4], ndmin=5)
print(arr)
print('shape of array :', arr.shape)

元组的形状代表什么?

每个索引处的整数表明相应维度拥有的元素数量。

上例中的索引 4,我们的值为 4,因此可以说第 5 个 ( 4 + 1 th) 维度有 4 个元素。

NumPy 数组重塑

重塑意味着更改数组的形状。

数组的形状是每个维中元素的数量。

通过重塑,我们可以添加或删除维度或更改每个维度中的元素数量。

从 1-D 重塑为 2-D

实例

将以下具有 12 个元素的 1-D 数组转换为 2-D 数组。

最外面的维度将有 4 个数组,每个数组包含 3 个元素:

import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(4, 3)
print(newarr)

从 1-D 重塑为 3-D

实例

将以下具有 12 个元素的 1-D 数组转换为 3-D 数组。

最外面的维度将具有 2 个数组,其中包含 3 个数组,每个数组包含 2 个元素:

import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(2, 3, 2)
print(newarr)

我们可以重塑成任何形状吗?

是的,只要重塑所需的元素在两种形状中均相等。

我们可以将 8 元素1D 数组重塑为 2 行 2D 数组中的 4 个元素,但是我们不能将其重塑为 3 元素 3 行 2D 数组,因为这将需要 3x3 = 9 个元素。

实例

尝试将具有 8 个元素的 1D 数组转换为每个维度中具有 3 个元素的 2D 数组(将产生错误):

import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
newarr = arr.reshape(3, 3)
print(newarr)

返回副本还是视图?

实例

检查返回的数组是副本还是视图:

import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
print(arr.reshape(2, 4).base)

上面的例子返回原始数组,因此它是一个视图。

未知的维

您可以使用一个“未知”维度。

这意味着您不必在 reshape 方法中为维度之一指定确切的数字。

传递 -1 作为值,NumPy 将为您计算该数字。

实例

将 8 个元素的 1D 数组转换为 2x2 元素的 3D 数:

import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8])
newarr = arr.reshape(2, 2, -1)
print(newarr)

注释:我们不能将 -1 传递给一个以上的维度。

展平数组

展平数组(Flattening the arrays)是指将多维数组转换为 1D 数组。

我们可以使用 reshape(-1) 来做到这一点。

实例

把数组转换为 1D 数组:

import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
newarr = arr.reshape(-1)
print(newarr)

注释:有很多功能可以更改 numpy flatten、ravel 中数组形状,还可以重新排列元素 rot90、flip、fliplr、flipud 等。这些功能属于 numpy 的中级至高级部分。

NumPy数组迭代

迭代意味着逐一遍历元素。

当我们在 numpy 中处理多维数组时,可以使用 python 的基本 for 循环来完成此操作。

如果我们对 1-D 数组进行迭代,它将逐一遍历每个元素。

实例

迭代以下一维数组的元素:

import numpy as np
arr = np.array([1, 2, 3])
for x in arr:
  print(x)

迭代 2-D 数组

在 2-D 数组中,它将遍历所有行。

实例

迭代以下二维数组的元素:

import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
for x in arr:
  print(x)

如果我们迭代一个 n-D 数组,它将逐一遍历第 n-1 维。

如需返回实际值、标量,我们必须迭代每个维中的数组。

实例

迭代 2-D 数组的每个标量元素:

import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
for x in arr:
  for y in x:
    print(y)

迭代 3-D 数组

在 3-D 数组中,它将遍历所有 2-D 数组。

实例

迭代以下 3-D 数组的元素:

import numpy as np
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
for x in arr:
  print(x)

要返回实际值、标量,我们必须迭代每个维中的数组。

实例

迭代到标量:

import numpy as np
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
for x in arr:
  for y in x:
    for z in y:
      print(z)

使用 nditer() 迭代数组

函数 nditer() 是一个辅助函数,从非常基本的迭代到非常高级的迭代都可以使用。它解决了我们在迭代中面临的一些基本问题,让我们通过例子进行介绍。

迭代每个标量元素

在基本的 for 循环中,迭代遍历数组的每个标量,我们需要使用 n 个 for 循环,对于具有高维数的数组可能很难编写。

实例

遍历以下 3-D 数组:

import numpy as np
arr = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
for x in np.nditer(arr):
  print(x)

迭代不同数据类型的数组

我们可以使用 op_dtypes 参数,并传递期望的数据类型,以在迭代时更改元素的数据类型。

NumPy 不会就地更改元素的数据类型(元素位于数组中),因此它需要一些其他空间来执行此操作,该额外空间称为 buffer,为了在 nditer() 中启用它,我们传参 flags=[‘buffered’]。

实例

以字符串形式遍历数组:

import numpy as np
arr = np.array([1, 2, 3])
for x in np.nditer(arr, flags=['buffered'], op_dtypes=['S']):
  print(x)

以不同的步长迭代

我们可以使用过滤,然后进行迭代。

实例

每遍历 2D 数组的一个标量元素,跳过 1 个元素:

import numpy as np
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
for x in np.nditer(arr[:, ::2]):
  print(x)

使用 ndenumerate() 进行枚举迭代

枚举是指逐一提及事物的序号。

有时,我们在迭代时需要元素的相应索引,对于这些用例,可以使用 ndenumerate() 方法。

实例

枚举以下 1D 数组元素:

import numpy as np
arr = np.array([1, 2, 3])
for idx, x in np.ndenumerate(arr):
  print(idx, x)

实例

枚举以下 2D 数组元素:

import numpy as np
arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
for idx, x in np.ndenumerate(arr):
  print(idx, x)
相关文章
|
3月前
|
存储 索引 Python
一文掌握python数组numpy的全部用法(零基础学python(二))
一文掌握python数组numpy的全部用法(零基础学python(二))
34 0
|
5天前
|
存储 索引 Python
NumPy 数组切片及数据类型介绍
了解 NumPy 数组切片,用于从数组中提取子集。一维数组切片使用 `start:end:step`,如 `arr[1:5]`。二维数组切片如 `arr[1:3, 0:3]`。创建 5x5 数组并练习切片,例如打印第一行、第二列、对角线元素和 2x2 子数组。别忘了检查数据类型,如 `arr.dtype`,并使用 `astype()` 转换类型。
19 0
|
6天前
|
存储 索引 Python
NumPy 数组创建方法与索引访问详解
NumPy 的 `ndarray` 是其核心数据结构,可通过 `array()`、`zeros()`、`ones()` 和 `empty()` 函数创建。`array()` 可以将列表等转换为数组;`zeros()` 和 `ones()` 生成全零或全一数组;`empty()` 创建未定义值的数组。此外,还有 `arange()`、`linspace()`、`eye()` 和 `diag()` 等特殊函数。练习包括使用这些函数创建特定数组。
113 1
|
14天前
|
存储 数据挖掘 API
【NumPy基础】- Numpy数组和矢量计算
【NumPy基础】- Numpy数组和矢量计算
|
16天前
|
机器学习/深度学习 测试技术 数据处理
Numpy Tile:数组复制的艺术与效率之键
【4月更文挑战第21天】
21 0
|
24天前
|
存储 数据采集 数据处理
《Numpy 简易速速上手小册》第6章:Numpy 高级数组操作(2024 最新版)
《Numpy 简易速速上手小册》第6章:Numpy 高级数组操作(2024 最新版)
31 1
《Numpy 简易速速上手小册》第6章:Numpy 高级数组操作(2024 最新版)
|
24天前
|
存储 算法 数据处理
《Numpy 简易速速上手小册》第3章:Numpy 数组操作与变换(2024 最新版)
《Numpy 简易速速上手小册》第3章:Numpy 数组操作与变换(2024 最新版)
35 0
|
24天前
|
存储 数据采集 数据挖掘
《Numpy 简易速速上手小册》第2章:Numpy 数据类型和数组构造(2024 最新版)
《Numpy 简易速速上手小册》第2章:Numpy 数据类型和数组构造(2024 最新版)
26 0
|
24天前
|
架构师 Java Python
NumPy 系列教程 001:入门和使用数组
NumPy 系列教程 001:入门和使用数组
20 0
|
25天前
|
存储 机器学习/深度学习 数据挖掘
自定义数据类型与NumPy结构数组详解
【4月更文挑战第17天】本文详细介绍了NumPy中的自定义数据类型和结构数组。通过`numpy.dtype`可创建自定义数据类型,如示例中的包含整数和浮点数字段的数组。结构数组能存储不同类型的元素,每行作为一个记录,包含多个字段。创建结构数组时,定义字段及其数据类型,然后通过字段名进行访问和操作。掌握这些技术能提升数据处理效率和灵活性,尤其在科学计算和数据分析领域。