gpt4 book ai didi

python - 从iterable设置numpy数组值的有效方法

转载 作者:太空宇宙 更新时间:2023-11-04 08:45:42 26 4
gpt4 key购买 nike

我有一个已分配给定大小的大型 numpy 数组。例如

my_array = numpy.empty(10000, numpy.float)

数组的值可以通过(模拟示例)生成

k * val ** 2 for val in range(0, 10000)

设置数组值的这一步要进行多次。例如,for k in range(0,1000)。除了开始时由 numpy.empty() 完成的分配外,我不想做任何其他分配。

我考虑过,

my_array = numpy.array([k*val**2 for val in range(0,10000)])

但这看起来至少会分配列表 [k * val ** 2 for val in range(0, 10000)]。是吗?

我也看到了numpy.fromiter , 但这似乎是为了构造数组。

my_array = numpy.fromiter((k*val**2 for val in range(0,10000)), numpy.float, 10000)

这里真的还有一个分配吗?


为了查看 numpy.fromiter 是否分配了一个数组,我尝试了以下操作

import numpy as np

iterable1 = (x*x for x in range(5))
iterable2 = (x*x + 1.0 for x in range(5))
my_array = np.fromiter(iterable1, np.float)
print(my_array)
print(hex(id(my_array)))

my_array = np.fromiter(iterable2, np.float)
print(my_array)
print(hex(id(my_array)))

在输出 I 中打印的两个地址是不同的。这是否意味着 np.fromiter 分配了一个新数组,然后将其分配给 my_array

最佳答案

根据评论中的解释,问题似乎是:

  • 大型数组需要经常更新,并尽可能高效;
  • 更新的来源不仅是其他 numpy 数组,还有任意 Python 对象(可以即时生成)。

第二项是问题所在:只要您的值来自 Python,将它们放入 numpy 数组中永远不会真正有效。这是因为您必须遍历解释代码中的每个值。

I was expecting to find the expression for ind, elem in enumerate(iterable): my_array[ind] = elem already packaged in a built in function. Do you know if the Python interpreter compiles that expression as a whole?

CPython 的虚拟机与 C++ 模型有很大不同;具体来说,编译器无法内联表达式或将其作为一个整体进行解释,从而显着提高效率。即使它支持在 C 中执行这一特定操作的字节码指令,它仍然需要调用生成器的 next 方法,该方法在执行 Python 字节后将每个值生成为堆分配的 Python 对象。代码。无论哪种情况,每次迭代都涉及解释代码,您确实希望避免这种情况。

解决问题的有效方法是从头开始设计它,永远不要离开 numpy。正如其他人在评论中所解释的那样,与在 Python 中实际逐个处理数据的成本相比,分配成本(如果有效地通过 numpy 完成)是微不足道的。我会设计如下:

  • 从头开始将尽可能多的代码转换为原生使用 numpy 数组;使返回一个 numpy 数组成为你的接口(interface)的一部分,不用担心分配成本。在 numpy 本身内做尽可能多的循环,所以它们是在 native 代码中完成的。永远不要在 Python 中遍历大型数组的所有值。
  • 在无法使用 numpy 的地方,尽早使用 numpy.fromiter 将迭代器转换为 numpy 数组。
  • 使用 my_array[:] = new_array[:]my_array = new_array 将新值引入数组。 (前者在微观上会花费更多时间,但当 my_array 在数据模型的许多地方共享时更有意义。)
  • Benchmark 您感兴趣的操作。不要假设“复制很慢” - 它可能会证明在 C++ 中“慢”的操作比 C++ 快几个数量级在 C++ 中高效的操作的 Python 再现。

如果在执行上述操作后,一些 numpy 不支持的操作,并且测量显示它非常低效,您可以使用 Python/C API创建一个扩展模块来高效地执行计算并将结果作为在 C 中创建的 numpy 数组返回。

关于python - 从iterable设置numpy数组值的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40899860/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com