我正在尝试在形状为 400, 800, 3 的 numpy ndarray 中找到唯一像素。我可以使用
np.unique(im.reshape(-1, 3), axis=0)
准确地得到我想要的东西,但是 np.unique 对于我的应用程序来说太慢了,因为它对数组进行排序。我发现this答案似乎提供了更快的选择。但是,由于它会展平数组,因此它会给出唯一的单个整数,而不是唯一的 RGB 颜色值。如何使用 numpy 获得唯一的 RGB 值?
在
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
标准
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