2024-10-06 12:25:54 发布
网友
假设您有一个2D数组(作为NumPyint数组),如下所示:
int
[[2,2,3,3], [2,3,3,3], [3,3,4,4]]
现在,您希望得到一个形状相同的数组,但不是原始值,而是用其出现的次数替换该数字。也就是说,数字2变为3,因为发生了3次,3s变成7s,4s变成2s
所以输出结果是:
我的解决方案是首先创建一个字典,它将所有原始值保存为键,并将出现的次数作为值。20000x2000的数组看起来很慢。在
我如何才能更有效地实现这一目标?在
谢谢!在
一种方法是使用numpy.unique来提取值计数。在
numpy.unique
然后转换为字典并使用numpy.vectorize来使用这个字典映射。在
numpy.vectorize
import numpy as np A = np.array([[2,2,3,3], [2,3,3,3], [3,3,4,4]]) d = dict(zip(*np.unique(A.ravel(), return_counts=True))) res = np.vectorize(d.get)(A) array([[3, 3, 7, 7], [3, 7, 7, 7], [7, 7, 2, 2]], dtype=int64)
性能
我看到上面的方法对于2000x2000数组需要~2s,而通过基于字典的方法是3s。但是PaulPanzer和{a2}的纯numpy溶液仍然更快。在
numpy
我相信您应该可以在这里通过使用return_inverse在np.unique()内使用return_inverse:
return_inverse
np.unique()
If True, also return the indices of the unique array (for the specified axis, if provided) that can be used to reconstruct ar.
ar
>>> import numpy as np >>> a = np.array([[2,2,3,3], ... [2,3,3,3], ... [3,3,4,4]]) >>> _, inv, cts = np.unique(a, return_inverse=True, return_counts=True) >>> cts[inv].reshape(a.shape) array([[3, 3, 7, 7], [3, 7, 7, 7], [7, 7, 2, 2]])
这也适用于扁平数组未排序的情况,例如b = np.array([[1, 2, 4], [4, 4, 1]])。在
b = np.array([[1, 2, 4], [4, 4, 1]])
以下是一种利用值为int的方法:
MAX_LOOKUP = 2**24 def f_pp(a): mn, mx = a.min(), a.max() span = mx-mn+1 if span > MAX_LOOKUP: raise RuntimeError('values spread to wide') a = a - mn return np.bincount(a.ravel(), None, span)[a]
时间安排(主要基于@jpp的工作):
一种方法是使用
numpy.unique
来提取值计数。在然后转换为字典并使用
numpy.vectorize
来使用这个字典映射。在性能
我看到上面的方法对于2000x2000数组需要~2s,而通过基于字典的方法是3s。但是PaulPanzer和{a2}的纯
^{pr2}$numpy
溶液仍然更快。在我相信您应该可以在这里通过使用
return_inverse
在np.unique()
内使用return_inverse
:这也适用于扁平数组未排序的情况,例如
b = np.array([[1, 2, 4], [4, 4, 1]])
。在以下是一种利用值为int的方法:
时间安排(主要基于@jpp的工作):
^{pr2}$相关问题 更多 >
编程相关推荐