更快的 numpy.unique 替代方案

问题描述 投票:0回答:2

我正在尝试在形状为 400, 800, 3 的 numpy ndarray 中找到唯一像素。我可以使用

np.unique(im.reshape(-1, 3), axis=0)
准确地得到我想要的东西,但是 np.unique 对于我的应用程序来说太慢了,因为它对数组进行排序。我发现this答案似乎提供了更快的选择。但是,由于它会展平数组,因此它会给出唯一的单个整数,而不是唯一的 RGB 颜色值。如何使用 numpy 获得唯一的 RGB 值?

python python-3.x numpy numpy-ndarray
2个回答
1
投票

numpy
pandas
之间进行(非常)快速的检查表明,即使进行所有必需的转换,如果不关心排序,
pandas.unique
也优于
numpy

这是如何运作的:

import numpy as np
import pandas as pd
import timeit

x = np.random.randint(0, 256, (400, 800, 3))


tic = timeit.default_timer()
uniques = np.unique(x.reshape(-1, 3), axis=0)
toc = timeit.default_timer()
print("numpy", toc-tic)

tic = timeit.default_timer()
xt = x.reshape(-1, 3).T
uniques = pd.Series(zip(xt[0], xt[1], xt[2])).unique()
toc = timeit.default_timer()
print("pandas", toc-tic)
>>> numpy 0.31687320000492036
>>> pandas 0.22542680002516136

0
投票

标准

set
将是最快的:

import timeit

import numpy as np
import pandas as pd

x = np.random.randint(0, 256, (400, 800, 3))


tic = timeit.default_timer()
uniques = np.unique(x.reshape(-1, 3), axis=0)
toc = timeit.default_timer()
print(f"{len(uniques)=}")
print("numpy", toc - tic)

tic = timeit.default_timer()
xt = x.reshape(-1, 3).T
uniques = pd.Series(zip(xt[0], xt[1], xt[2])).unique()
toc = timeit.default_timer()
print(f"{len(uniques)=}")
print("pandas", toc - tic)

tic = timeit.default_timer()
uniques = set(zip(x.flat[::3], x.flat[1::3], x.flat[2::3]))
toc = timeit.default_timer()
print(len(uniques))
print("set", toc - tic)

tic = timeit.default_timer()
l1, l2, l3 = x.flat[::3].tolist(), x.flat[1::3].tolist(), x.flat[2::3].tolist()
uniques = set(zip(l1, l2, l3))
toc = timeit.default_timer()
print(f"{len(uniques)=}")
print("tolist() + set", toc - tic)

在我的计算机上打印(AMD 5700x):

len(uniques)=316930
numpy 0.22756228200159967

len(uniques)=316930
pandas 0.13342827907763422

len(uniques)=316930
set 0.07360963500104845

len(uniques)=316930
tolist() + set 0.10639729397371411
© www.soinside.com 2019 - 2024. All rights reserved.