填充数组的最快方法?

时间:2019-05-23 20:28:53

标签: python algorithm mod

我想像这样填充一个大小为n的数组(一个很大的数组):

1 for i = 1, (n/2)+1
2 for i = 2, 3, ... , (n/2)
0 for i = (n/2)+2, ... , n

最快的方法是迭代0到n并为每个语句使用if语句和%吗?

赞:

array = []
for index in range(1,n):
    if index == 1 or (index % ((n/2)+1) == 0):
        array.append(1)
    if index == 2 or index == 3 or (index % (n/2) == 0):
        array.append(2)
    if (index % ((n/2)+2) == 0):
        array.append(0)

我试图想出其他方法来做到这一点,但我还没有提出任何建议。我不是行业程序员,但不确定如何实现此目标。

4 个答案:

答案 0 :(得分:1)

您可能要为此使用numpy。您可以使用np.r_连接多个切片,并使用它们对数组进行切片分配:

import numpy as np

n = 10
a = np.zeros(n)
a[np.r_[0,n//2]] = 1
a[np.r_[1:n//2]] = 2
a[np.r_[n//2+1:n]] = 0

print(a)
array([1., 2., 2., 2., 2., 1., 0., 0., 0., 0.])

答案 1 :(得分:1)

由于其他答案都与numpy数组一起使用,它们非常快,因此我想添加一些其他答案以确保完整性。 (在最初的问题中,如果n为奇数,以及作者期望的是基于零的索引还是基于一的索引,显然存在一些歧义。)

您可以使用列表理解功能简单地创建列表

[1 if i in [0, n/2] else (2 if i <=(n/2) else 0) for i in range(0, n)]

但是更快的方法是通过扩展类来扩展列表的功能:

class NewThing(list):
    def __init__(self, n):
        self.n = n
    def __getitem__(self,i):
        if i in {0,n/2}:
            return 1
        elif i <=n/2:
            return 2
        return 0
    def to_list(self):
        return [self[i] for i in range(0, n)]

>>>unique_list = NewThing(len(u))
>>>unique_list[4]
2
>>>unique_list.to_list()
[1, 2, 2, 2, 2, 1, 0, 0, 0, 0]

您可以调用整个列表,也可以仅调用单个元素。创建整个列表仍然很慢。

答案 2 :(得分:1)

构造此类集合的最有效方法是使用numpy数组。

我们可以使用以下方法构造它:

import numpy as np

def generate_array(n):
    a = np.hstack((np.full(n//2+1, 2), np.zeros(n//2-1)))
    a[[0, n//2]] = 1
    return a

例如:

>>> generate_array(6)
array([1., 2., 2., 1., 0., 0.])
>>> generate_array(10)
array([1., 2., 2., 2., 2., 1., 0., 0., 0., 0.])
>>> generate_array(16)
array([1., 2., 2., 2., 2., 2., 2., 2., 1., 0., 0., 0., 0., 0., 0., 0.])

时间

对于n=100_000,我们得到:

>>> timeit(partial(generate_array, 100_000), number=10_000)
1.0764452270013862

对于n=1_000_000,我们得到:

>>> timeit(partial(generate_array, 1_000_000), number=1_000)
6.448311180000019

生成100k个元素的数组大约需要花费(包括小开销的partial等)。 107.64 µs ,生成1M个元素的数组需要花费 6448.31µs < / em>。

答案 3 :(得分:1)

甚至n

def generate_array2(n):
    a = np.empty((2,n//2))
    a[0]=2
    a[1]=0
    a[:,0]=1
    return a.ravel()

%timeit a= generate_array2(1_000_000)
491 ± 6.58 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)