gpt4 book ai didi

python - 使用第二个数组作为引用对 numpy 数组的元素进行分类

转载 作者:太空狗 更新时间:2023-10-30 02:44:03 25 4
gpt4 key购买 nike

假设我有一个包含有限数量的唯一值的数组。说

data = array([30, 20, 30, 10, 20, 10, 20, 10, 30, 20, 20, 30, 30, 10, 30])

我还有一个引用数组,其中包含在 data 中找到的所有唯一值, 没有重复并且按照特定的顺序。说

reference = array([20, 10, 30])

我想创建一个与 data 形状相同的数组包含 reference 中的索引作为值data 中每个元素的数组找到数组。

换句话说,有 datareference , 我想创建一个数组 indexes使得以下内容成立。

data = reference[indexes]

计算 indexes 的次优方法会像这样使用 for 循环

indexes = np.zeros_like(data, dtype=int)
for i in range(data.size):
indexes[i] = np.where(data[i] == reference)[0]

但令我惊讶的是,没有numpythonic(因此速度更快!)的方法来做到这一点……有什么想法吗?

谢谢!

最佳答案

我们有 datareference 作为 -

In [375]: data
Out[375]: array([30, 20, 30, 10, 20, 10, 20, 10, 30, 20, 20, 30, 30, 10, 30])

In [376]: reference
Out[376]: array([20, 10, 30])

暂时,让我们考虑一个排序版本的reference -

In [373]: np.sort(reference)
Out[373]: array([10, 20, 30])

现在,我们可以使用np.searchsorted找出每个 data 元素在此排序版本中的位置,就像这样 -

In [378]: np.searchsorted(np.sort(reference), data, side='left')
Out[378]: array([2, 1, 2, 0, 1, 0, 1, 0, 2, 1, 1, 2, 2, 0, 2], dtype=int64)

如果我们运行原始代码,预期的输出结果是 -

In [379]: indexes
Out[379]: array([2, 0, 2, 1, 0, 1, 0, 1, 2, 0, 0, 2, 2, 1, 2])

可以看出,searchsorted 输出很好,除了其中的 0 必须是 11 必须更改为 0。现在,我们已经将 reference 的排序版本纳入计算。因此,要进行 01 的更改,反之亦然,我们需要引入用于排序 reference 的索引,即 np.argsort(引用)。这基本上就是矢量化无循环或无字典方法!所以,最终的实现看起来像这样 -

# Get sorting indices for reference
sort_idx = np.argsort(reference)

# Sort reference and get searchsorted indices for data in reference
pos = np.searchsorted(reference[sort_idx], data, side='left')

# Change pos indices based on sorted indices for reference
out = np.argsort(reference)[pos]

运行时测试 -

In [396]: data = np.random.randint(0,30000,150000)
...: reference = np.unique(data)
...: reference = reference[np.random.permutation(reference.size)]
...:
...:
...: def org_approach(data,reference):
...: indexes = np.zeros_like(data, dtype=int)
...: for i in range(data.size):
...: indexes[i] = np.where(data[i] == reference)[0]
...: return indexes
...:
...: def vect_approach(data,reference):
...: sort_idx = np.argsort(reference)
...: pos = np.searchsorted(reference[sort_idx], data, side='left')
...: return sort_idx[pos]
...:

In [397]: %timeit org_approach(data,reference)
1 loops, best of 3: 9.86 s per loop

In [398]: %timeit vect_approach(data,reference)
10 loops, best of 3: 32.4 ms per loop

验证结果-

In [399]: np.array_equal(org_approach(data,reference),vect_approach(data,reference))
Out[399]: True

关于python - 使用第二个数组作为引用对 numpy 数组的元素进行分类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31078160/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com