首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python数组中元素的迭代减法

Python数组中元素的迭代减法
EN

Stack Overflow用户
提问于 2017-03-24 20:24:39
回答 4查看 1.7K关注 0票数 1

我有一个很大的块状数组。是否有一种方法可以将每个元素减去其下面的元素,并将结果存储在一个新的列表/数组中,而无需使用循环。

我的意思是一个简单的例子:

代码语言:javascript
运行
复制
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是数组的大小。

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

谢谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-03-24 21:41:04

下面是一种基于masking的方法,用于广播减法后的提取和掩膜的制作,我们再次使用了broadcasting (可以说是双broadcasting驱动)-

代码语言:javascript
运行
复制
r = np.arange(a.size)
out = (a[:, None] - a)[r[:,None] < r]

运行时测试

矢量法-

代码语言:javascript
运行
复制
# @user2357112's solution
def pairwise_diff_triu_indices_based(a):
    return (a[:, None] - a)[np.triu_indices(len(a), k=1)]

# Proposed in this post
def pairwise_diff_masking_based(a):
    r = np.arange(a.size)
    return (a[:, None] - a)[r[:,None] < r]

时间安排-

代码语言:javascript
运行
复制
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

更仔细地研究涉及到的性能参数

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

创建掩码有多大帮助?

代码语言:javascript
运行
复制
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在创建掩码方面的改进,而不是索引设置。

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

代码语言:javascript
运行
复制
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的改进。

票数 2
EN

Stack Overflow用户

发布于 2017-03-24 20:39:26

代码语言:javascript
运行
复制
temp = a[:, None] - a
result = temp[np.triu_indices(len(a), k=1)]

执行所有成对减法以产生temp,包括从自身减去元素和从后面的元素减去早期元素,然后使用triu_indices来选择我们想要的结果。(a.)

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

代码语言:javascript
运行
复制
In [13]: a = numpy.arange(2000)

In [14]: %%timeit
   ....: temp = a[:, None] - a
   ....: 
100 loops, best of 3: 6.99 ms per loop

In [15]: %%timeit
   ....: temp = a[:, None] - a
   ....: result = temp[numpy.triu_indices(len(a), k=1)]
   ....: 
10 loops, best of 3: 51.7 ms per loop
票数 3
EN

Stack Overflow用户

发布于 2017-03-24 20:32:59

代码语言:javascript
运行
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43008527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档