Python中数组元素的迭代减法

2024-03-29 14:38:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个大的纽比阵列。有没有一种方法可以在不使用循环的情况下,减去每个元素及其下面的元素,并将结果存储到一个新的列表/数组中。

一个简单的例子说明我的意思:

a = numpy.array([4,3,2,1])

result = [4-3, 4-2, 4-1, 3-2, 3-1, 2-1] = [1, 2, 3, 1, 2 ,1]

请注意,我使用的“real”数组不包含序列中的数字。这只是为了简化示例。

我知道结果应该是(n-1)!元素,其中n是数组的大小。

有没有一种方法可以不使用循环,而是以“智能”的方式重复数组?

谢谢!


Tags: 方法numpy元素示例列表智能方式情况
3条回答
temp = a[:, None] - a
result = temp[np.triu_indices(len(a), k=1)]

执行所有成对减法以生成temp,包括从元素本身减去元素,从后面的元素中减去较早的元素,然后使用triu_indices来选择我们想要的结果。(^{} adds an extra length-1 axis to ^{}。)

请注意,几乎所有的运行时都花在从temp构造result(因为triu_indices很慢,并且使用索引来选择数组的上三角也很慢)。如果可以直接使用temp,则可以节省大量时间:

^{pr2}$
a = [4, 3, 2, 1]
differences = ((x - y) for i, x in enumerate(a) for y in a[i+1:])
for diff in differences:
  # do something with difference.
  pass

这里有一个基于^{}的方法,用于广播减法后的提取和掩码的创建,我们再次使用broadcasting(可以这样说,双broadcasting提供了动力)-

r = np.arange(a.size)
out = (a[:, None] - a)[r[:,None] < r]

运行时测试

矢量化方法-

^{pr2}$

时间安排-

In [109]: a = np.arange(2000)

In [110]: %timeit pairwise_diff_triu_indices_based(a)
10 loops, best of 3: 36.1 ms per loop

In [111]: %timeit pairwise_diff_masking_based(a)
100 loops, best of 3: 11.8 ms per loop

进一步了解相关性能参数

让我们深入研究一下这个设置的时间安排,来研究基于掩码的方法有多大帮助。现在,比较有两个部分-掩码创建与索引创建和基于掩码的布尔索引与基于整数的索引。在

创建遮罩有多大帮助?

In [37]: r = np.arange(a.size)

In [38]: %timeit np.arange(a.size)
1000000 loops, best of 3: 1.88 µs per loop

In [39]: %timeit r[:,None] < r
100 loops, best of 3: 3 ms per loop

In [40]: %timeit np.triu_indices(len(a), k=1)
100 loops, best of 3: 14.7 ms per loop

关于5x相对于索引设置的掩码创建的改进。在

布尔索引对基于整数的索引有多大帮助?

In [41]: mask = r[:,None] < r

In [42]: idx = np.triu_indices(len(a), k=1)

In [43]: subs = a[:, None] - a

In [44]: %timeit subs[mask]
100 loops, best of 3: 4.15 ms per loop

In [45]: %timeit subs[idx]
100 loops, best of 3: 10.9 ms per loop

关于2.5x的改进。在

相关问题 更多 >