- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有两个 N
float 数组(充当 (x,y)
坐标并且可能有重复项)和关联的 z
N
float 组(充当坐标的权重)。
对于每个 (x,y)
浮点对,我需要选择具有最小关联 z
值的对。我已经定义了一个执行此操作的 selectMinz()
函数(请参阅下面的代码),但它花费的时间太长。
我怎样才能提高这个函数的性能?
import numpy as np
import time
def getData():
N = 100000
x = np.arange(0.0005, 0.03, 0.001)
y = np.arange(6., 10., .05)
# Select N values for x,y, where values can be repeated
x = np.random.choice(x, N)
y = np.random.choice(y, N)
z = np.random.uniform(10., 15., N)
return x, y, z
def selectMinz(x, y, z):
"""
Select the minimum z for each (x,y) pair.
"""
xy_unq, z_unq = [], []
# For each (x,y) pair
for i, xy in enumerate(zip(*[x, y])):
# If this xy pair was already stored in the xy_unq list
if xy in xy_unq:
# If the stored z value associated with this xy pair is
# larger than this new z[i] value
if z_unq[xy_unq.index(xy)] > z[i]:
# Store this smaller value instead
z_unq[xy_unq.index(xy)] = z[i]
else:
# Store the xy pair, and its associated z value
xy_unq.append(xy)
z_unq.append(z[i])
return xy_unq, z_unq
# Define data with the proper format.
x, y, z = getData()
s = time.clock()
xy_unq, z_unq = selectMinz(x, y, z) # <-- TAKES TOO LONG (~15s in my system)
print(time.clock() - s)
最佳答案
步骤:
lex-sort
使x-y
对按顺序排列。或者,我们可以使用缩放方法将一个数组按另一个数组的值范围缩放,然后将其与另一个数组相加,最后使用 argsort
获得 lex 排序的等效索引。 np.minimum.reduceat
获取间隔中的最小值,由对分组定义。因此,我们将有一个矢量化解决方案,就像这样 -
def selectMinz_vectorized(x, y, z):
# Get grouped lex-sort indices
sidx = (y + x*(y.max() - y.min() + 1)).argsort()
# or sidx = np.lexsort([x, y])
# Lex-sort x, y, z
x_sorted = x[sidx]
y_sorted = y[sidx]
z_sorted = z[sidx]
# Get equality mask between each sorted X and Y elem against previous ones.
# The non-zero indices of its inverted mask gives us the indices where the
# new groupings start. We are calling those as cut_idx.
seq_eq_mask = (x_sorted[1:] == x_sorted[:-1]) & (y_sorted[1:] == y_sorted[:-1])
cut_idx = np.flatnonzero(np.concatenate(( [True], ~seq_eq_mask)))
# Use those cut_idx to get intervalled minimum values
minZ = np.minimum.reduceat(z_sorted, cut_idx)
# Make tuples of the groupings of x,y and the corresponding min Z values
return (zip(x_sorted[cut_idx], y_sorted[cut_idx]), minZ.tolist())
sample 运行-
In [120]: np.c_[x,y,z]
Out[120]:
array([[ 0., 1., 69.],
[ 2., 0., 47.],
[ 1., 0., 62.],
[ 0., 2., 33.],
[ 1., 7., 32.],
[ 1., 0., 50.],
[ 2., 0., 55.]])
In [121]: selectMinz(x,y,z) # original method
Out[121]:
([(0.0, 1.0), (2.0, 0.0), (1.0, 0.0), (0.0, 2.0), (1.0, 7.0)],
[69.0, 47.0, 50.0, 33.0, 32.0])
In [122]: selectMinz_vectorized(x,y,z)
Out[122]:
([(1.0, 0.0), (2.0, 0.0), (0.0, 1.0), (0.0, 2.0), (1.0, 7.0)],
[50.0, 47.0, 69.0, 33.0, 32.0])
这是我最初的方法,涉及创建堆叠数组然后执行这些操作。实现看起来像这样 -
def selectMinz_vectorized_v2(x, y, z):
d = np.column_stack((x,y,z))
sidx = np.lexsort(d[:,:2].T)
b = d[sidx]
cut_idx = np.r_[0,np.flatnonzero(~(b[1:,:2] == b[:-1,:2]).all(1))+1]
minZ = np.minimum.reduceat(b[:,-1], cut_idx)
return ([tuple(i) for i in b[cut_idx,:2]], minZ.tolist())
矢量化方法的基准测试
方法-
# Pruned version of the approach posted earlier
def selectMinz_vectorized_pruned(x, y, z):
sidx = (y + x*(y.max() - y.min() + 1)).argsort()
x_sorted = x[sidx]
y_sorted = y[sidx]
z_sorted = z[sidx]
seq_eq_mask = (x_sorted[1:] == x_sorted[:-1]) & (y_sorted[1:] == y_sorted[:-1])
cut_idx = np.flatnonzero(np.concatenate(( [True], ~seq_eq_mask)))
minZ = np.minimum.reduceat(z_sorted, cut_idx)
return x_sorted[cut_idx], y_sorted[cut_idx], minZ
def numpy_indexed_app(x,y,z): # @Eelco Hoogendoorn's soln
return npi.group_by((x, y)).min(z)
时间 -
In [141]: x,y,z=getData(10000)
In [142]: %timeit selectMinz_vectorized_pruned(x, y, z)
...: %timeit numpy_indexed_app(x,y,z)
...:
1000 loops, best of 3: 763 µs per loop
1000 loops, best of 3: 1.09 ms per loop
In [143]: x,y,z=getData(100000)
In [144]: %timeit selectMinz_vectorized_pruned(x, y, z)
...: %timeit numpy_indexed_app(x,y,z)
...:
100 loops, best of 3: 8.53 ms per loop
100 loops, best of 3: 12.9 ms per loop
关于python - 从第三个数组中的两个数组中有效地获取每对元素的最小值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45887270/
在开发中的网页上,我在 IE 上遇到此错误 element = $(element); 此代码位于prototype.js 预期对象 如何消除此错误。 更新: 现场也使用了 jQuery。 最佳答
我有两个大小相同的嵌套数组: Array1 =[[1, 2], [], [2, 3]] Array2= [[1, 4], [8, 11], [3, 6]] 我需要将它们合并到一个数组中,如下所示: A
我有一些 jQuery 代码,当单击具有特定 ID 的项目时运行。当 ID 是 的一部分时,它就可以工作。元素,但当它位于 中时则不然元素。为什么会这样呢?我想使用 an,因为如果用户关闭了 Ja
Flex-box 规范 3声明 flex 元素不是 block 容器: A flex item establishes a new formatting context for its content
我遇到了一个意想不到的问题。 HTML JS $(function() { var $divs = $('.myDiv'); // create new div not in
我使用 Bootstrap 和 Ember.js 得到了一个无序列表。每个列表项都是一个显示新帖子的链接,每当您单击该链接时,Ember 都会添加类 active默认情况下。我正在使用 Bootstr
我正在尝试让一个函数正常工作,但运气不佳,所以我想向 Stackoverflow 智囊团提出一个新手问题! 基本上,我有一个表单,并且循环遍历所有元素以查看是否存在自定义数据属性。如果存在,则保持该元
我想映射一个可选数组,删除那些 nil 值,并使用另一个函数映射非 nil 值。 我知道我可以通过使用 compactMap 然后使用常规 map 来实现这一点,但我只想遍历数组一次。 我为此实现了一
我如何定位 li 元素,除非它们出现在 之后元素?换句话说,我想针对步骤而不是注释。 我尝试向 OL 添加一个我想从选择中排除的类,但我想出的代码不起作用。 (顺便说一句,重构 html 不是一种选
Warning 1 The element 'system.webServer' has invalid child element 'rewrite'. List of possible eleme
我正在尝试编写一个脚本,该脚本将遍历 HTML 源并创建 DOM 的 JSON 文件,然后使用 d3.js 在 TreeView 中显示该文件。我遇到的问题是不仅希望显示元素(TITLE、P、LI 等
我有以下 HTML 表单:- Option 1 Option 2
我试图在选定的 HTML 元素之后选择下一个具有类名 slider-value 的 span 元素。我尝试了多种解决方案,但没有一个有效。 我可以通过 id 选择它,但我不希望那样做使代码冗余。 $(
如果电子邮件地址无效,我想在屏幕上显示一条消息“请输入有效的电子邮件地址”。 body 元素的innerHTML 语句工作正常,但我用于p 元素的innerHTML 语句不起作用。 有一次,当我测试它
以下 jQuery 代码调用 ul 元素,查找元素内的前 三个 li 列表项,并隐藏剩余的 li 项目。然后,它附加一个 li 元素,其中显示“显示更多...”,并且在单击时显示之前隐藏的列表项。 (
我问了a question早些时候关于将编辑/删除链接与 h1 元素内联的最佳方法。我能够通过给出的答案实现这一点,但我现在有额外的要求,我需要在 h1 下方显示一个段落并编辑/删除链接。 到目前为止
我使用 MVC 4 和 knockout.js 库版本 2.1.0 显示从服务器检索到的大量文件的表中的以下摘录。 0)"> 正在正确检索数据,
我创建了一个脚本,该脚本在鼠标悬停在父容器上时激活,并且应该将其子元素移离鼠标。我目前已经让它工作了,但是代码的某些部分似乎与 REACT 代码应该是什么样子相矛盾。特别是两个部分。 我在渲染函数中使
我是 JS 新手,正在尝试理解项目 https://github.com/tastejs/todomvc 的代码 请参阅屏幕截图,我尝试对 button X 以及其父元素 div 设置断点,但在这两种
例如,假设有一个带有奇特颜色的标记: Something written here 使用 Visual Studio 2017 和 MVC 5 元素,有没有办法检查和定位当前应用了哪些样式,以及负责它
我是一名优秀的程序员,十分优秀!