python-3.x Faster Alternative to numpy.unique

hxzsmxv2  于 2023-10-21  发布在  Python
关注(0)|答案(2)|浏览(84)

我想在一个形状为400,800,3的numpy ndarray中找到唯一的像素。我可以用np.unique(im.reshape(-1, 3), axis=0)得到我想要的东西,但是np.unique对我的应用程序来说太慢了,因为它对数组进行排序。我发现this答案似乎提供了一个更快的选择。但是,因为它是数组的整数,所以它给出唯一的单个整数,而不是唯一的RGB颜色值。如何使用numpy获得唯一的rgb值?

n7taea2i

n7taea2i1#

numpypandas之间的(非常)快速检查表明,即使所有需要的转换,如果排序不是问题,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
35g0bw71

35g0bw712#

标准set将是最快的:

from timeit import timeit

import numpy as np
import pandas as pd

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

t1 = timeit("u = np.unique(x.reshape(-1, 3), axis=0)", number=1, globals=globals())
t2 = timeit(
    "xt = x.reshape(-1, 3).T;pd.Series(zip(xt[0], xt[1], xt[2])).unique()",
    number=1,
    globals=globals(),
)
t3 = timeit(
    "u = set(zip(x.flat[::3], x.flat[1::3], x.flat[2::3]))", number=1, globals=globals()
)
t4 = timeit(
    "l1, l2, l3 = x.flat[::3].tolist(), x.flat[1::3].tolist(), x.flat[2::3].tolist();u = set(zip(l1, l2, l3))",
    number=1,
    globals=globals(),
)

print(f"np.unique      {t1:>10.3f}")
print(f"pd.Series      {t2:>10.3f}")
print(f"set            {t3:>10.3f}")
print(f"tolist() + set {t4:>10.3f}")

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

np.unique           0.233
pd.Series           0.117
set                 0.058
tolist() + set      0.040

相关问题