Python 附加值的更快方法

Python 附加值的更快方法,python,optimization,numpy,append,Python,Optimization,Numpy,Append,假设我有一个大的浮点值列表,并且我只想选择其中的一部分来查看其他数组: result = [] for x,s in zip(xlist, slist): if f(s): result.append(x) 在循环开始时,我可以粗略估计通过f选择的条目数 现在这个速度非常慢,我尝试将list更改为array,但只看附加,速度会变慢 def f(v): for ii in a: v.append(ii) a = range(int(1E7)) v = [] t = time();

假设我有一个大的浮点值列表,并且我只想选择其中的一部分来查看其他数组:

result = []
for x,s in zip(xlist, slist):
    if f(s): result.append(x)
在循环开始时,我可以粗略估计通过
f
选择的条目数

现在这个速度非常慢,我尝试将
list
更改为
array
,但只看附加,速度会变慢

def f(v):
    for ii in a: v.append(ii)
a = range(int(1E7))
v = []
t = time(); f(v); print time()-t # -> 1.3
v = array.array('i')
t = time(); f(v); print time()-t # -> 3.4

我需要更快,因为这个循环在我的程序中非常慢。
numpy.array
能帮我吗?没有
append
方法。

可能有更好的numpy解决方案,但在纯python中,您可以尝试迭代器:

from itertools import izip

xlist = [1,2,3,4,5,6,7,8]
slist = [0,1,0,1,0,0,0,1]

def f(n):
    return n

results = (x for x,s in izip(xlist, slist) if f(s))

# results is an iterator--you don't have values yet
# and no extra memory is consumed
# you can retrieve results one by one with iteration
# or you can exhaust all values and store in a list

assert list(results)==[2,4,8]

# you can use an array too
# import array
# a = array.array('i', results)
您还可以将此方法与numpy阵列相结合,看看它是否更快。看

但是,如果您可以将代码重新构造为使用迭代器,则可以避免生成完整列表,从而完全避免使用
append

不言而喻,您应该看看是否可以加快过滤函数的速度,因为每个元素都会调用它一次。

请尝试以下方法:

从python文档中:

Deques是堆栈和队列的泛化(名称读作“deck”,是“双端队列”的缩写)。deque支持线程安全、内存高效的附加和弹出,在deque的任意一侧,在任意方向上的O(1)性能大致相同

虽然列表对象支持类似的操作,但它们针对快速的固定长度操作进行了优化,并为pop(0)和insert(0,v)操作带来了O(n)内存移动成本,这两种操作都会更改基础数据表示的大小和位置

在我的系统上(由于内存有限,我使用的范围为1e6):


根据问题中的第一句话,您希望根据其他列表或数组中的值选择值

在numpy中,可以使用索引从数组中获取选定值。我在示例中使用。这样可以避免将值附加到现有数组中,但可以将选定值的副本作为数组提供。 您可以使用numpy或您自己的函数中的
&
|
运算符组合多个条件

In [1]: import numpy as np

In [2]: size = int(1E7)

In [3]: ar = np.arange(size)

In [4]: ar2 = np.random.randint(100, size=size)

In [5]: %timeit ar[(ar2 > 50) & (ar2 < 70) | (ar2 == 42)]
10 loops, best of 3: 249 ms per loop

通常应该避免在numpy数组上循环,而是使用矢量化函数来操作数组

好的,听起来不错。假设现在我有很多选择。如果值通过
selection1
,则将其放入
ar1
,如果通过
selection2
则放入
ar2
。。。。选择类似于
1010@wiso希望这是您现在要问的是的,您的解决方案很简单,关键是您必须循环每个选择的数据,这不是最佳的
In [1]: import numpy as np

In [2]: size = int(1E7)

In [3]: ar = np.arange(size)

In [4]: ar2 = np.random.randint(100, size=size)

In [5]: %timeit ar[(ar2 > 50) & (ar2 < 70) | (ar2 == 42)]
10 loops, best of 3: 249 ms per loop
conditions = [(10, 20), (20, 50)] # min, max as tuples in a list
results = {}
for condition in conditions:
    selection = ar[(ar2 > condition[0]) & (ar2 < condition[1])]
    # do something with the selection ?
    results[condition] = selection
print results
{(20, 50): array([      2,       6,       7, ..., 9999993, 9999997, 9999998]),
 (10, 20): array([      1,       3,      66, ..., 9999961, 9999980, 9999999])}