5

我希望加快以下代码的速度:

NNlist=[np.unique(i) for i in NNlist] 

其中 NNlist 是具有重复条目的 np.arrays 列表。

谢谢 :)

4

5 回答 5

5

numpy.unique已经非常优化,除非您对基础数据有所了解,否则您不太可能获得比现有数据更快的速度。例如,如果数据都是您可以使用的小整数,numpy.bincount或者如果每个数组中的唯一值基本相同,则可以对整个数组列表进行一些优化。

于 2012-12-03T17:59:05.133 回答
4

pandas.unique()比 快得多numpy.unique()。Pandas 版本不对结果进行排序,但您可以自己进行排序,如果结果比输入小得多(即有很多重复值),它仍然会快得多:

np.sort(pd.unique(arr))

时间:

In [1]: x = np.random.randint(10, 20, 50000000)

In [2]: %timeit np.sort(pd.unique(x))
201 ms ± 9.32 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [3]: %timeit np.unique(x)
1.49 s ± 27.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
于 2018-06-05T08:14:53.777 回答
1

我还查看list(set())了列表中的和字符串,介于熊猫系列和 python 列表之间。

data = np.random.randint(0,10,100)
data_hex = [str(hex(n)) for n in data] # just some simple strings

sample1 = pd.Series(data, name='data')
sample2 = data.tolist()

sample3 = pd.Series(data_hex, name='data')
sample4 = data_hex

然后是基准:

%timeit np.unique(sample1) # 16.4 µs ± 464 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.unique(sample2) # 15.9 µs ± 743 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit np.unique(sample3) # 45.8 µs ± 5.88 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit np.unique(sample4) # 20.6 µs ± 680 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit pd.unique(sample1) # 60.3 µs ± 5.39 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit pd.unique(sample2) # 196 µs ± 18.7 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit pd.unique(sample3) # 79.7 µs ± 3.98 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit pd.unique(sample4) # 214 µs ± 61 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each

%timeit list(set(sample1)) # 16.3 µs ± 1.63 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit list(set(sample2)) # 1.64 µs ± 83.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit list(set(sample3)) # 17.8 µs ± 1.96 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit list(set(sample4)) # 2.48 µs ± 439 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

要点是:

  • 从带有整数的 Pandas 系列开始?要么选择np.unique()要么list(set())

  • 从带字符串的 Pandas 系列开始?一起去list(set())

  • 从整数列表开始?一起去list(set())

  • 从字符串列表开始?一起去list(set())

但是,如果 N=1,000,000 而不是,结果会有所不同。

%timeit np.unique(sample1) # 26.5 ms ± 616 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit np.unique(sample2) # 98.1 ms ± 3.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit np.unique(sample3) # 1.31 s ± 78.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit np.unique(sample4) # 174 ms ± 2.57 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit pd.unique(sample1) # 10.5 ms ± 472 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit pd.unique(sample2) # 99.3 ms ± 5.24 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit pd.unique(sample3) # 46.4 ms ± 4.73 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit pd.unique(sample4) # 113 ms ± 11.7 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit list(set(sample1)) # 25.9 ms ± 2.11 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit list(set(sample2)) # 11.2 ms ± 496 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit list(set(sample3)) # 37.1 ms ± 1.28 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit list(set(sample4)) # 20.2 ms ± 843 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
  • 从带有整数的 Pandas 系列开始?一起去pd.unique()

  • 从带字符串的 Pandas 系列开始?一起去list(set())

  • 从整数列表开始?一起去list(set())

  • 从字符串列表开始?一起去list(set())

于 2018-08-23T18:23:09.397 回答
0

以下是一些基准:

In [72]: ar_list = [np.random.randint(0, 100, 1000) for _ in range(100)]

In [73]: %timeit map(np.unique, ar_list)
100 loops, best of 3: 4.9 ms per loop

In [74]: %timeit [np.unique(ar) for ar in ar_list]
100 loops, best of 3: 4.9 ms per loop

In [75]: %timeit [pd.unique(ar) for ar in ar_list] # using pandas
100 loops, best of 3: 2.25 ms per loop

所以pandas.unique似乎比numpy.unique. 然而,文档字符串提到这些值“不一定是排序的”,这(部分)解释了它更快。在此示例中使用列表推导或map没有区别。

于 2012-12-03T20:32:44.643 回答
0

numpy.unique()是基于排序(quicksort),而是pandas.unique()基于哈希表。通常,根据我的基准,后者更快。它们已经非常优化。对于一些特殊情况,可以继续优化性能。例如,如果数据已经排序,则可以跳过排序方法:

# ar is already sorted
# this segment is from source code of numpy
mask = np.empty(ar.shape, dtype=np.bool_)
mask[:1] = True
mask[1:] = ar[1:] != ar[:-1]
ret = ar[mask]

我遇到了和你类似的问题。我写了我的unique函数供我使用。因为pandas.unique不支持return_counts选项。这是快速实施。但我的实现只支持整数数组。您可以在此处查看源代码。

于 2020-12-29T17:19:32.753 回答