- 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/
我在使用 Android 时遇到了一点问题。 我有我的 GPS 位置,明确的经纬度,以及以米为单位的搜索射线(例如 100 米),可以吗? 想象一下我在射线形成的圆心的位置,我会知道如何在 Andro
深夜的编程之旅 这是一个深夜,街头灯光昏暗,大部分人都已陷入梦乡。但对于我来说,这却是一个灵感迸发的时刻。窗外的星空仿佛在诉说着某种宇宙的密码,而键盘下的代码则是我解密这个宇宙的工具。 一个突如其来的
我将数据集结构定义为 struct Dataset: Hashable { var x: Double var y: Double } 然后是数组 var dataset: [Data
我在 Excel 文件中有一个摘要选项卡,需要查看应计选项卡才能找到 Max和 Min .我遇到的问题是有许多不同的位置/商品组合,我需要找到 Max和 Min基于位置/商品组合。位置和商品位于两个单
我有一个 Excel 表,其中包含两列感兴趣的年份和捐款。年份值为 2008,2009,2010 等... 我想获得 2009 年所有捐款中的最低金额。我试过了 MIN(IF(Year="2009",
到现在为止,我刚刚找到了为列表中多个数据帧中的列获取最大值的解决方案。 我已经将数据帧 df1, df2, df3, ..., dfn 存储在列表 dfList 中,我想获取列 df_ 的最大值$a
假设我有一个列名列表作为向量: vec=c("C1" , "C2" ,"C3"). 我知道这些列名来自数据框 df: df: C1 C2 C3 C4 C5 1 2 3 4 5 1 4
我需要计算大数组的最小值/最大值。我知道Math.max.apply() ,但在大型数组上,它会因堆栈溢出异常而失败。有什么简单的解决方案吗? 最佳答案 使用 sort() 对数组进行排序方法它使用快
例如,我有一个像这样的模型: class Record(models.Model): name = CharField(...) price = IntegerField(...)
我正在编写一个用于测试听力的简单应用,并且正在使用Audiotrack生成纯音。因为它是用于测试听力的应用程序,所以我使用非常低的音量来播放这些音调。 要设置音量,我使用音轨的 setVolume(f
Example data set 对,上面是我的数据集子段图像的链接。它以 3 列为一组,第一个是浓度,第二个是限定值,最后一个是 MDL - 并持续最多 95 个 sample (因此总共 285
我想计算 df 的每 n 行的最小值/最大值,比如 10,但是使用 df.rolling(10).max() 给出第 0-9、1-10、2-11 行的值等。我想要 0-9、10-19、20-29 等
我被问到了关于 c# 的同样问题 here我发现通过使用 linq 你可以轻松地做到这一点。 但是既然 java 中的 linq 没有其他选择,我该如何简单地做到这一点呢? 最佳答案 如果您想要类似于
我曾经使用过数组,并且知道如何对使用数值(double 和 int)的数组进行排序,但我必须使用字符串数组制作相同的应用程序。我的教授不允许我发挥“创造力”,也不允许我与其他可能有助于完成这项工作的静
我想知道通过这样的回溯获得某些事实的最大值(最年长的人)是否是个好主意: data(MaxID, MaxName, MaxAge), \+ (data(ID, Name, Age), ID \= Ma
我想计算 df 的每 n 行的最小值/最大值,比如 10,但是使用 df.rolling(10).max() 给出第 0-9、1-10、2-11 行的值等。我想要 0-9、10-19、20-29 等
我的数据如下所示: df <- tribble( ~A, ~B, 0.2, 0.1, 0.2, 0.3, 0.5, 0.1, 0.7, 0.9,
我有以下数据集 Date Category 2014-01-01 A 2014-01-02 A 2014-01-03 A 2014-01-04
我是使用 Python 进行数据分析的初学者,并且坚持以下几点: 我想使用广播/矢量化方法从各个列 (pandas.dataframe) 中找到最大值(value)。 我的数据框的快照如下: 最佳答案
C99 中是否有一个标准函数来使用给定的比较函数获取给定数组中的最小/最大元素。 类似: void* get_min(void* start,size_t size,size_t elementSiz
我是一名优秀的程序员,十分优秀!