获取列表差异的有效方法

问题描述 投票:0回答:2

我正在沿着一条直线轨迹移动一个粒子,并将轨迹除以 N,其中 N 是一个大数。然后我根据它的位置做一些计算并将它们存储在 7 个不同的列表中。整个过程大约需要 0.03 秒,这很棒。

但是,然后使用这些列表,我创建了差异列表,其中 d_list 的元素只是 list[n+1]-list[n] for all n。为此,我使用以下代码

d_lists = [[np.abs(b-a) for a,b in zip(l, l[1:])] for l in lists]

当我这样做时,现在需要 7.7 秒,这比 0.03 秒高得多。我试着跟随减少时间,但花了大约 13 秒。

d_lists = [[abs_diff for abs_diff in map(np.abs, zip(l, l[1:]))]

我很好奇是否有更好的方法来解决这个问题。我很难直观地理解为什么这个简单的任务需要很多时间。

我注意到的一件事是 np.abs 造成的。如果我只是做 (b-a) 而不是 np.abs(b-a) 那么 7.7 秒减少到 1.2 秒。

python python-3.x optimization list-comprehension
2个回答
0
投票

您可以完全在

numpy
中使用
diff
abs
来做到这一点:

d_lists = np.abs(np.diff(lists))

这将给出一个数组,您可以使用

转换回列表列表(如果需要)
d_lists = [list(l) for l in d_lists]

0
投票

你试过了吗
np.diff

这为您提供了数组中的顺序差异,而无需您当前从标准 python 结果 b-a 转换每个元组 (a,b),然后运行 numpy 函数的过程。

d_lists = [np.abs(np.diff(l)) for l in lists]

是否可以将列表本身作为 numpy 数组?

这可能会使它更快。从本机 Python 变量到 NumPy 的每次转换都可能会产生少量开销,在您当前的情况下,这是大量重复的。

为了获得最大效率,您可以将所有列表存储在一个single numpy array

我认为这是可能的,因为你似乎在说这 7 个列表实际上是平行的,即它们的长度相等。

如果是这样,那么您可以使用

np.diff
并指定您希望它沿哪个“轴”变化。

https://numpy.org/doc/stable/reference/generated/numpy.diff.html

numpy.diff(a, n=1, axis=-1, prepend=<no value>, append=<no value>)

Calculate the n-th discrete difference along the given axis.

The first difference is given by out[i] = a[i+1] - a[i] along the 
given axis, higher differences are calculated by using diff 
recursively.

Parameters:

a, array_like, Input array

n, int, optional The number of times values are differenced. 

axis, int, optional The axis along which the difference is taken, default is the last axis.
© www.soinside.com 2019 - 2024. All rights reserved.