series.unique vs set of list - performance

Vik*_*ari 4 python unique pandas

我有一个包含多列的pandas数据框.目的是在其中一列中找到唯一值.

实现这一目标的两种方法是:

  • 获取该系列的一组列表: list(set(data['Day']))

  • 使用pandas的功能获取唯一身份 data['Day'].unique()

在我的试验中,set方法工作得更快.在大多数情况下这是真的吗?为什么不呢?任何其他资源利用含义?

还请添加其中任何一个更好的原因.

chr*_*isb 8

它取决于数据类型.对于数字类型,pd.unique应该明显更快.

对于存储为python对象的字符串,将会有一个小得多的差异,并且set()通常具有竞争力,因为它做的事情非常相似.

一些例子:

strs = np.repeat(np.array(['a', 'b', 'c'], dtype='O'), 10000)

In [11]: %timeit pd.unique(strs)
558 µs ± 16.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [12]: %timeit list(set(strs))
531 µs ± 13.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

nums = np.repeat(np.array([1, 2, 3]), 10000)

In [13]: %timeit pd.unique(nums)
230 µs ± 9.28 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [14]: %timeit list(set(nums))
2.16 ms ± 71 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)


Max*_*axU 5

对具有很少唯一值的列使用分类 dtype 是有意义的。

演示:

 df = pd.DataFrame(np.random.choice(['aa','bbbb','c','ddddd','EeeeE','xxx'], 10**6), columns=['Day'])

In [34]: %timeit list(set(df['Day']))
98.1 ms ± 2.96 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [35]: %timeit df['Day'].unique()
82.9 ms ± 56.5 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)

1M 行的时间几乎相同

让我们测试类别 dtype:

In [37]: df['cat'] = df['Day'].astype('category')

In [38]: %timeit list(set(df['cat']))
93.7 ms ± 766 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [39]: %timeit df['cat'].unique()
25.1 ms ± 6.57 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)

更新: 1.000.000 行 DF 中的 500 个唯一值:

In [75]: a = pd.util.testing.rands_array(10, 500)

In [76]: df = pd.DataFrame({'Day':np.random.choice(a, 10**6)})

In [77]: df.shape
Out[77]: (1000000, 1)

In [78]: df.Day.nunique()
Out[78]: 500

In [79]: %timeit list(set(df['Day']))
55 ms ± 395 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [80]: %timeit df['Day'].unique()
133 ms ± 3.34 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [81]: df['cat'] = df['Day'].astype('category')

In [82]: %timeit list(set(df['cat']))
102 ms ± 3.64 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [83]: %timeit df['cat'].unique()
38.3 ms ± 1.47 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)

结论:在您的真实数据上“计时”总是更好 - 您可能会得到不同的结果......