python - Numpy:如何快速替换矩阵中的相等值?
问题描述
假设我们有一个 rank 2 数组a
,其中的n
条目包含 in 中的整数值{0,1,2,...,m}
。现在对于这些整数中的每一个,我想找到a
具有此值的条目的索引(index_i, index_j
在以下示例中调用)。(所以我正在寻找的np.unique(...,return_index=True)
只是二维数组,并且有可能返回每个唯一值的所有索引。)
一种天真的方法将涉及使用布尔索引,这会导致O(m*n)
操作(见下文),但我只想有O(n)
操作。虽然我找到了一个解决方案,但我觉得应该有一个内置的方法,或者至少可以简化这个 - 或者至少可以删除这些丑陋的循环:
import numpy as np
a = np.array([[0,0,1],[0,2,1],[2,2,1]])
m = a.max()
#"naive" in O(n*m)
i,j = np.mgrid[range(a.shape[0]), range(a.shape[1])]
index_i = [[] for _ in range(m+1)]
index_j = [[] for _ in range(m+1)]
for k in range(m+1):
index_i[k] = i[a==k]
index_j[k] = j[a==k]
#all the zeros:
print(a[index_i[0], index_j[0]])
#all the ones:
print(a[index_i[1], index_j[1]])
#all the twos:
print(a[index_i[2], index_j[2]])
#"sophisticated" in O(n)
index_i = [[] for _ in range(m+1)]
index_j = [[] for _ in range(m+1)]
for i in range(a.shape[0]):
for j in range(a.shape[1]):
index_i[a[i,j]].append(i)
index_j[a[i,j]].append(j)
#all the zeros:
print(a[index_i[0], index_j[0]])
#all the ones:
print(a[index_i[1], index_j[1]])
#all the twos:
print(a[index_i[2], index_j[2]])
(请注意,稍后我将需要这些索引进行写访问,即替换存储在数组中的值。但在这些操作之间,我确实需要二维结构。)
解决方案
这是一个基于在sorting
迭代以保存为具有键是唯一元素和值作为索引的字典时的最小工作量的意图 -
shp = a.shape
idx = a.ravel().argsort()
idx_sorted = np.c_[np.unravel_index(idx,shp)]
count = np.bincount(a.ravel())
valid_idx = np.flatnonzero(count!=0)
cs = np.r_[0,count[valid_idx].cumsum()]
out = {e:idx_sorted[i:j] for (e,i,j) in zip(valid_idx,cs[:-1],cs[1:])}
样本输入、输出 -
In [155]: a
Out[155]:
array([[0, 2, 6],
[0, 2, 6],
[2, 2, 1]])
In [156]: out
Out[156]:
{0: array([[0, 0],
[1, 0]]), 1: array([[2, 2]]), 2: array([[0, 1],
[1, 1],
[2, 0],
[2, 1]]), 6: array([[0, 2],
[1, 2]])}
如果序列中的所有整数都包含在数组中,我们可以稍微简化一下 -
shp = a.shape
idx = a.ravel().argsort()
idx_sorted = np.c_[np.unravel_index(idx,shp)]
cs = np.r_[0,np.bincount(a.ravel()).cumsum()]
out = {iterID:idx_sorted[i:j] for iterID,(i,j) in enumerate(zip(cs[:-1],cs[1:]))}
推荐阅读
- linux - 如何在 shell 脚本中使用 `time` 命令?
- typescript - 如何在订阅中调用服务,但在更新之前不等待服务完成
- css - 如何将引导原色更改为线性渐变?
- php - MariaDB 中的日文字符存储问题
- delphi - 如何检查 Delphi 上的 RichView 是否为空?
- node.js - Npm 'Dev' Watchify/Browserify/vueify cmd 编译 Vue 组件并启动 Express 服务器失败?(服务器无法启动)
- vuejs2 - elementui tooltip组件如何延迟消失,
- swift - 有没有办法让泛型对象没有泛型类型?
- javascript - 带科尔多瓦的点移动扫描仪不工作
- python - 除以 0. 值并在结果中强制数字