gpt4 book ai didi

python - 如何加速 numpy 数组的枚举/如何有效地枚举 numpy 数组?

转载 作者:太空宇宙 更新时间:2023-11-03 12:50:35 24 4
gpt4 key购买 nike

我需要生成很多随机数。我试过使用 random.random 但这个函数很慢。因此我切换到更快的 numpy.random.random !到目前为止,一切都很好。生成的随机数实际上用于计算某些东西(基于数字)。因此,我枚举每个数字并替换值。这似乎扼杀了我之前获得的所有加速。以下是使用 timeit() 生成的统计数据:

test_random - no enumerate
0.133111953735
test_np_random - no enumerate
0.0177130699158


test_random - enumerate
0.269361019135
test_np_random - enumerate
1.22525310516

如您所见,使用 numpy 生成数字的速度几乎快 10 倍,但枚举这些数字的运行时间相同。

下面是我使用的代码:

import numpy as np
import timeit
import random

NBR_TIMES = 10
NBR_ELEMENTS = 100000

def test_random(do_enumerate=False):
y = [random.random() for i in range(NBR_ELEMENTS)]
if do_enumerate:
for index, item in enumerate(y):
# overwrite the y value, in reality this will be some function of 'item'
y[index] = 1 + item

def test_np_random(do_enumerate=False):
y = np.random.random(NBR_ELEMENTS)
if do_enumerate:
for index, item in enumerate(y):
# overwrite the y value, in reality this will be some function of 'item'
y[index] = 1 + item

if __name__ == '__main__':
from timeit import Timer

t = Timer("test_random()", "from __main__ import test_random")
print "test_random - no enumerate"
print t.timeit(NBR_TIMES)

t = Timer("test_np_random()", "from __main__ import test_np_random")
print "test_np_random - no enumerate"
print t.timeit(NBR_TIMES)


t = Timer("test_random(True)", "from __main__ import test_random")
print "test_random - enumerate"
print t.timeit(NBR_TIMES)

t = Timer("test_np_random(True)", "from __main__ import test_np_random")
print "test_np_random - enumerate"
print t.timeit(NBR_TIMES)

加快速度的最佳方法是什么?为什么 enumerate 会如此显着地减慢速度?

编辑:我使用 enumerate 的原因是因为我需要当前元素的索引和值。

最佳答案

要充分利用 numpy 的速度,您需要创建 ufuncs只要有可能。将 vectorize 应用于 mgibsonbr 的函数建议是一种方法,但如果可能的话,更好的方法是简单地构造一个利用 numpy 内置 ufunc 的函数。所以像这样:

>>> import numpy
>>> a = numpy.random.random(10)
>>> a + 1
array([ 1.29738145, 1.33004628, 1.45825441, 1.46171177, 1.56863326,
1.58502855, 1.06693054, 1.93304272, 1.66056379, 1.91418473])
>>> (a + 1) * 0.25 / 4
array([ 0.08108634, 0.08312789, 0.0911409 , 0.09135699, 0.09803958,
0.09906428, 0.06668316, 0.12081517, 0.10378524, 0.11963655])

您想在 numpy 数组中应用的函数的性质是什么?如果您告诉我们,也许我们可以帮助您设计出一个仅使用 numpy ufuncs 的版本。

不使用 enumerate 也可以生成索引数组。 Numpy 提供 ndenumerate ,这是一个迭代器,可能更慢,但它也提供了 indices ,这是生成与数组中的值相对应的索引的一种非常快速的方法。所以……

>>> numpy.indices(a.shape)
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])

所以更明确地说,您可以使用上面的内容并使用 numpy.rec.fromarrays 组合它们:

>>> a = numpy.random.random(10)
>>> ind = numpy.indices(a.shape)
>>> numpy.rec.fromarrays([ind[0], a])
rec.array([(0, 0.092473494150913438), (1, 0.20853257641948986),
(2, 0.35141455604686067), (3, 0.12212258656960817),
(4, 0.50986868372639049), (5, 0.0011439325711705139),
(6, 0.50412473457942508), (7, 0.28973489788728601),
(8, 0.20078799423168536), (9, 0.34527678271856999)],
dtype=[('f0', '<i8'), ('f1', '<f8')])

听起来您主要关心的是就地执行操作。使用 vectorize 很难做到这一点,但使用 ufunc 方法很容易:

>>> def somefunc(a):
... a += 1
... a /= 15
...
>>> a = numpy.random.random(10)
>>> b = a
>>> somefunc(a)
>>> a
array([ 0.07158446, 0.07052393, 0.07276768, 0.09813235, 0.09429439,
0.08561703, 0.11204622, 0.10773558, 0.11878885, 0.10969279])
>>> b
array([ 0.07158446, 0.07052393, 0.07276768, 0.09813235, 0.09429439,
0.08561703, 0.11204622, 0.10773558, 0.11878885, 0.10969279])

如您所见,numpy 就地执行这些操作。

关于python - 如何加速 numpy 数组的枚举/如何有效地枚举 numpy 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9792925/

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