ash*_*ets 3 python arrays numpy
我有一个整数标签数组,我想确定每个标签有多少个,并将这些值存储在与输入大小相同的数组中。这可以通过以下循环来完成:
def counter(labels):
sizes = numpy.zeros(labels.shape)
for num in numpy.unique(labels):
mask = labels == num
sizes[mask] = numpy.count_nonzero(mask)
return sizes
Run Code Online (Sandbox Code Playgroud)
带输入:
array = numpy.array([
[0, 1, 2, 3],
[0, 1, 1, 3],
[3, 1, 3, 1]])
Run Code Online (Sandbox Code Playgroud)
counter() 返回:
array([[ 2., 5., 1., 4.],
[ 2., 5., 5., 4.],
[ 4., 5., 4., 5.]])
Run Code Online (Sandbox Code Playgroud)
然而,对于具有许多独特标签的大型阵列,在我的例子中为 60,000,这需要相当长的时间。这是复杂算法的第一步,我不能在这一步上花费超过 30 秒。是否已经存在可以完成此操作的功能?如果没有,我如何加速现有循环?
方法#1
这是一个使用np.unique-
_, tags, count = np.unique(labels, return_counts=1, return_inverse=1)
sizes = count[tags]
Run Code Online (Sandbox Code Playgroud)
方法#2
使用正数labels,更简单,更有效的方式np.bincount-
sizes = np.bincount(labels)[labels]
Run Code Online (Sandbox Code Playgroud)
运行时测试
设置具有60,000唯一的正数和两组这样的长度100,000并1000,000计时。
设置 #1:
In [192]: np.random.seed(0)
...: labels = np.random.randint(0,60000,(100000))
In [193]: %%timeit
...: sizes = np.zeros(labels.shape)
...: for num in np.unique(labels):
...: mask = labels == num
...: sizes[mask] = np.count_nonzero(mask)
1 loop, best of 3: 2.32 s per loop
In [194]: %timeit np.bincount(labels)[labels]
1000 loops, best of 3: 376 µs per loop
In [195]: 2320/0.376 # Speedup figure
Out[195]: 6170.212765957447
Run Code Online (Sandbox Code Playgroud)
设置 #2 :
In [196]: np.random.seed(0)
...: labels = np.random.randint(0,60000,(1000000))
In [197]: %%timeit
...: sizes = np.zeros(labels.shape)
...: for num in np.unique(labels):
...: mask = labels == num
...: sizes[mask] = np.count_nonzero(mask)
1 loop, best of 3: 43.6 s per loop
In [198]: %timeit np.bincount(labels)[labels]
100 loops, best of 3: 5.15 ms per loop
In [199]: 43600/5.15 # Speedup figure
Out[199]: 8466.019417475727
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
113 次 |
| 最近记录: |