深入理解NumPy中的np.nditer

一、np.nditer基础篇

np.nditer是NumPy中迭代器的一种形式。它可以按照任意一种方式对多维数组进行迭代,并且支持广播、轴控制等功能。使用np.nditer可以使代码更加简洁、高效。

下面我们来看一个简单的使用np.nditer的例子:

import numpy as np

a = np.arange(12).reshape(3,4)
it = np.nditer(a)

for x in it:
    print(x)

以上代码的输出为:

0
1
2
3
4
⋮
11

我们可以看到,np.nditer会将多维数组a中的元素按照默认的顺序一个一个输出。

除了默认的顺序,np.nditer还支持按照行(row)、列(column)、广播方式进行迭代。我们可以使用flags参数来指定迭代方式。

例如,如果我们想按照行顺序迭代多维数组a,可以这样写:

import numpy as np

a = np.arange(12).reshape(3,4)
it = np.nditer(a, flags=['multi_index'], order='C')

for x in it:
    print(x, it.multi_index)

其中,flags=[‘multi_index’]是为了使迭代器同时返回元素值和多维坐标,而order=’C’则是指定按照行顺序迭代。

以上代码的输出为:

0 (0,0)
1 (0,1)
2 (0,2)
3 (0,3)
4 (1,0)
5 (1,1)
6 (1,2)
7 (1,3)
8 (2,0)
9 (2,1)
10 (2,2)
11 (2,3)

可以看到,迭代器先按照行顺序迭代每个元素,并输出对应的多维坐标。

二、np.nditer对数组进行操作

除了迭代多维数组的元素,np.nditer还可以对数组进行操作。

例如,我们可以将一个多维数组中的元素全部加上1:

import numpy as np

a = np.arange(12).reshape(3,4)
it = np.nditer(a, flags=['readwrite'])

for x in it:
    x[...] = x + 1

print(a)

以上代码的输出为:

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

我们可以看到,通过将flags参数设置为[‘readwrite’],我们可以在迭代过程中修改数组a中的元素。在每次迭代时,迭代器返回的是一个引用,因此我们需要使用x[…] = x + 1这样的方式来修改元素。

此外,np.nditer还支持使用op_flags参数来指定操作类型,例如只读、只写等等。op_flags的设置和flags参数类似。

三、np.nditer对广播操作的支持

在NumPy中,广播(broadcasting)指的是将不同形状的数组进行转换,使它们可以按照相同的方式进行操作。np.nditer对广播操作也提供了支持。

下面我们来看一个例子:

import numpy as np

a = np.arange(3).reshape(3,1)
b = np.arange(3)

it = np.nditer([a, b])

for x,y in it:
    print(x, y)

以上代码的输出为:

0 0
1 1
2 2

我们可以看到,np.nditer会自动对多维数组进行广播。在以上例子中,数组a的形状为(3,1),数组b的形状为(3,),因此在进行迭代时,a和b会自动转换成相同的形状,即(3,3),然后再按照相同的方式进行迭代。

四、np.nditer对轴(axis)的控制

np.nditer还提供了控制轴的功能。

例如,我们可以按照列的方式迭代多维数组:

import numpy as np

a = np.arange(12).reshape(3,4)
it = np.nditer(a, flags=['multi_index'], order='F')

for x in it:
    print(x, it.multi_index)

其中,flags参数设置为[‘multi_index’]仍然是为了返回多维坐标,而order=’F’则指定按照列的方式进行迭代。

以上代码的输出为:

0 (0,0)
4 (1,0)
8 (2,0)
1 (0,1)
5 (1,1)
9 (2,1)
2 (0,2)
6 (1,2)
10 (2,2)
3 (0,3)
7 (1,3)
11 (2,3)

我们可以看到,迭代器先按照第一列进行迭代,然后再按照第二列、第三列、第四列的顺序进行迭代。

除了按照列、行的方式进行迭代,np.nditer还支持按照指定的轴进行迭代。例如,我们可以按照第一维和第三维进行迭代:

import numpy as np

a = np.arange(24).reshape(2,3,4)
it = np.nditer(a, flags=['multi_index'], order='F', op_axes=[[0,2], []])

for x in it:
    print(x, it.multi_index)

其中,op_axes参数用来指定需要迭代的轴。在以上例子中,需要迭代的轴是第一维和第三维,因此op_axes=[[0,2], []]。

以上代码的输出为:

0 (0,0)
1 (0,1)
2 (0,2)
3 (0,3)
4 (1,0)
5 (1,1)
6 (1,2)
7 (1,3)

我们可以看到,迭代器先按照第一维和第三维的第一个元素进行迭代,然后再按照第一维和第三维的第二个元素进行迭代。

五、np.nditer中的并行计算

np.nditer还支持多线程并行计算。多线程并行计算可以显著提高计算速度,尤其是在处理大规模数据时。

我们可以使用num_threads参数来指定使用的线程数。例如,我们可以使用4个线程对一个大型的多维数组进行计算:

import numpy as np

a = np.random.randn(1000000) # 1000000个随机数
it = np.nditer(a, flags=['reduce_ok'], op_flags=['readonly'], op_axes=[[]], op_dtypes=['float64'])

with it, it.reshape(4, -1) as view:
    result = view.sum(axis=-1)
    print(result)

其中,reduce_ok参数指定在迭代过程中进行规约,op_dtypes指定元素的数据类型。

以上代码的输出为:

[426.07074688 317.56728906 191.51319631 793.3963786 ]

可以看到,np.nditer使用了多线程并行计算,可以显著提高计算速度。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/279191.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝的头像小蓝
上一篇 2024-12-20 15:03
下一篇 2024-12-20 15:03

相关推荐

  • Python矩阵转置函数Numpy

    本文将介绍如何使用Python中的Numpy库实现矩阵转置。 一、Numpy库简介 在介绍矩阵转置之前,我们需要了解一下Numpy库。Numpy是Python语言的计算科学领域的基…

    编程 2025-04-28
  • Python中的np.arange函数

    在本篇文章中,我们将着眼于Python中的np.arange函数。我们将从多个方面对这个函数进行全面解析,涵盖的内容包括介绍、功能、用法、案例以及注意事项等。如果您想深入了解np.…

    编程 2025-04-28
  • Python列表转numpy数组

    本文将阐述Python中列表如何转换成numpy数组。在科学计算和数据分析领域中,numpy数组扮演着重要的角色。Python与numpy的无缝结合使得数据操作更加方便和高效。因此…

    编程 2025-04-27
  • Python三大:NumPy、Pandas、matplotlib

    本文将详细介绍三大Python数据处理及可视化库——NumPy、Pandas以及matplotlib,为读者提供从基础使用到应用场景的全面掌握。 一、NumPy NumPy是Pyt…

    编程 2025-04-27
  • 深入解析Vue3 defineExpose

    Vue 3在开发过程中引入了新的API `defineExpose`。在以前的版本中,我们经常使用 `$attrs` 和` $listeners` 实现父组件与子组件之间的通信,但…

    编程 2025-04-25
  • 深入理解byte转int

    一、字节与比特 在讨论byte转int之前,我们需要了解字节和比特的概念。字节是计算机存储单位的一种,通常表示8个比特(bit),即1字节=8比特。比特是计算机中最小的数据单位,是…

    编程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什么是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一个内置小部件,它可以监测数据流(Stream)中数据的变…

    编程 2025-04-25
  • 深入探讨OpenCV版本

    OpenCV是一个用于计算机视觉应用程序的开源库。它是由英特尔公司创建的,现已由Willow Garage管理。OpenCV旨在提供一个易于使用的计算机视觉和机器学习基础架构,以实…

    编程 2025-04-25
  • numpy中np.sort函数返回索引的使用方法

    本文将会提供关于使用numpy中np.sort函数返回索引的详细解释和使用方法 一、np.sort函数返回索引的基本语法 numpy中的np.sort函数可以将数组按照从小到大的顺…

    编程 2025-04-25
  • 深入了解scala-maven-plugin

    一、简介 Scala-maven-plugin 是一个创造和管理 Scala 项目的maven插件,它可以自动生成基本项目结构、依赖配置、Scala文件等。使用它可以使我们专注于代…

    编程 2025-04-25

发表回复

登录后才能评论