我有一个numpy数组,如下所示
array([[ 6, 5],
[ 6, 9],
[ 7, 5],
[ 7, 9],
[ 8, 10],
[ 9, 10],
[ 9, 11],
[10, 10]])我想选择元素,这样y坐标是唯一的。如果两个y坐标是相同的,我想选择小x坐标的元素。
预期产出
array([[ 6, 5],
[ 6, 9],
[ 8, 10],
[ 9, 11]])解释
选择[6,5]而不是[7,5]
选择[8,10]而不是[9,10]和[10,10]
拾取[9, 11]
谢谢
发布于 2018-07-08 23:06:07
首先,按照第一列进行排序:
a = a[a[:, 0].argsort()]使用带有return_index标志的np.unique返回唯一索引:
a[np.unique(a[:, 1], return_index=True)[1]]
array([[ 6, 5],
[ 6, 9],
[ 8, 10],
[ 9, 11]])一些时间安排:
a = np.random.randint(1, 10, 10000).reshape(-1, 2)
In [45]: %timeit rows_by_unique_y(a)
3.83 ms ± 137 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [46]: %timeit argsort_unique(a)
370 µs ± 8.26 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)是的,我的方法使用了初始排序,但是在Python中numpy but迭代中的矢量化操作。
发布于 2018-07-08 23:06:06
如果您愿意使用另一个库,我建议您使用索引来实现高效和紧凑的解决方案。
import numpy as np
import numpy_indexed as npi
a = np.array([[6, 5], [6, 9], [7, 5], [7, 9], [8, 10], [9, 10], [9, 11], [10, 10]])
column_to_groupby = 1
groups, reduced = npi.group_by(a[:,column_to_groupby]).min(a)
print(reduced)它提供了以下输出
[[ 6 5]
[ 6 9]
[ 8 10]
[ 9 11]]这是时间is的结果
In [5]: a = np.random.randint(1, 10, 10000).reshape(-1, 2)
In [6]: %timeit npi.group_by(a[:,1]).min(a)
354 µs ± 2.29 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)发布于 2018-07-08 22:59:28
一种方法循环遍历数组并记下您所见过的最佳值,然后在最后重构该数组:
import numpy as np
def rows_by_unique_y(arr):
best_for_y = defaultdict(lambda: float('inf'))
for i, row in enumerate(arr):
x,y = row[0], row[1]
best_for_y[y] = min(x, best_for_y[y])
return np.array([[x,y] for y, x in best_for_y.items()])
arr = np.array([[6, 5], [6, 9], [7, 5], [7, 9], [8, 10], [9, 10], [9, 11], [10, 10]])
print(rows_by_unique_y(arr))不需要分类,只需跟踪最小值。这一产出如下:
[[ 6 5]
[ 6 9]
[ 8 10]
[ 9 11]]虽然这个答案渐进地更快,但用户3483203的答案在实践中要好得多。这是因为它调用优化的C代码,而不是停留在Python令人惊讶的慢解释器中。但是,如果您的数组很大(几千兆字节),那么O(n log n)行为就会开始丢失。
同时,如果您的数组那么大,您可能应该使用像Spark这样的MapReduce框架。我给出的算法很容易并行化。
如果您不需要最小的x值,那么使用np.unique的下列一行可以工作:
arr[np.unique(arr[:,1], return_index=True)[1]]但这又回来了
array([[ 6, 5],
[ 6, 9],
[10, 10],
[ 9, 11]])如果您切换8和10。
https://stackoverflow.com/questions/51236510
复制相似问题