python - numpy.random.choice 的性能

标签 python performance numpy

我更新了代码和时间。

我正在尝试提高代码中函数的性能。我必须生成一个包含随机元素的列表。但是,列表的不同部分必须填充来自不同集合的元素。代码示例如下。我必须生成数百万个这样的列表,一次一个。

函数 foo1 是最快的,但它不能满足我的需要。它可供性能引用。函数 foo2 和 foo3 可以满足我的需要,但花费的处理时间几乎是 foo1 的三倍。

Python 2.7.9(默认,2015 年 2 月 10 日,03:29:19)。 Darwin 上的 [GCC 4.2.1 兼容 Apple LLVM 6.0 (clang-600.0.56)]。 numpy.版本 '1.8.1'

import numpy

import timeit

_ops_1 = ["-123.456", "3.1416", "1", "2"]
_ops_2 = ["ABC", "XYZ", 'A', 'B', 'C']

size = 10

def foo1 (): 
    return numpy.random.choice(_ops_1 + _ops_2, 5*size)

def foo2 (): 
    return list(numpy.concatenate((numpy.random.choice(_ops_1, 2*size), 
        numpy.random.choice(_ops_1 + _ops_2, size),
        numpy.random.choice(_ops_2, 2*size)), 0))

def foo3 (): 
    return numpy.random.choice(_ops_1, 2*size).tolist() + \
        numpy.random.choice(_ops_1 + _ops_2, size).tolist() + \
        numpy.random.choice(_ops_2, 2*size).tolist()

### Suggested by Divakar
def random_choice_replace_True(arr,size):
    return numpy.take(arr,numpy.random.randint(0,len(arr),size))

def foo4 (): 
    return random_choice_replace_True(_ops_1, 2*size).tolist() + \
        random_choice_replace_True(_ops_1 + _ops_2, size).tolist() + \
        random_choice_replace_True(_ops_2, 2*size).tolist()

### 2nd suggestion by Divakar
def random_choice_replace_True_idx(arr,size):
    return numpy.array(arr)[numpy.random.randint(0,len(arr),size)]

def foo5 (): 
    return random_choice_replace_True_idx(_ops_1, 2*size).tolist() + \
        random_choice_replace_True_idx(_ops_1 + _ops_2, size).tolist() + \
        random_choice_replace_True_idx(_ops_2, 2*size).tolist()

###########

setup = '''import numpy

_ops_1 = ["-123.456", "3.1416", "1", "2"]
_ops_2 = ["ABC", "XYZ", 'A', 'B', 'C']

size = 10'''

# As required, Number was increased to 10 million to get closer to actual timings
timeit.timeit(foo1, setup=setup, number=10000000)

timeit.timeit(foo2, setup=setup, number=10000000)

timeit.timeit(foo3, setup=setup, number=10000000)

timeit.timeit(foo4, setup=setup, number=10000000)

timeit.timeit(foo5, setup=setup, number=10000000)

我的机器上的运行时间是:

timeit.timeit(foo1, setup=setup, number=10000000) 235.22050380706787

timeit.timeit(foo2, setup=setup, number=10000000) 760.1884841918945

timeit.timeit(foo3, setup=setup, number=10000000) 560.77258586883545

timeit.timeit(foo4, setup=setup, number=10000000) 388.69550228118896

timeit.timeit(foo5, setup=setup, number=10000000) 252.32089233398438

好吧,现在我会接受 Divakar 提出的第二个建议,这个建议非常好。但欢迎其他建议!

最佳答案

那个 np.random.choice 及其可选参数 replace被设置为True返回从输入数组中随机选择的元素,并且这些元素可以重复。我们可以通过创建覆盖数组长度的随机索引并索引到数组中以进行选择来模拟这种行为。因此,我们可以用这样的东西来模拟内置 -

def random_choice_replace_True(A,size):
    return np.array(A)[np.random.randint(0,len(A),size)]

如果您处理的输入已经是 NumPy 数组,则可以跳过 np.array(A)部分进行转换并只需使用 A那里。

关于python - numpy.random.choice 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38375321/

相关文章:

python - Heroku 上的 webpack 和 django : bundling before collectstatic

python pandas reshape 数据框

python - Pandas 在 groupby 上组合列

c# - WMI 性能不佳

c# - 使用两个整数键存储信息的最快方法是什么?

python - Numpy:向量化二分支测试(类似三元运算符)

python - 如何在不保存到磁盘的情况下从 python 中的 numpy 数组创建 png 图像文件对象(对于 http 请求)

android - 在android中为ListView中的每一行制作动态布局

python - 使用openCV和numpy进行图像处理。尝试返回没有红色的图像

python - 无法将 Pandas Dataframe 列转换为 float