series.unique vs 集合列表 - 性能
series.unique vs list of set - performance
我有一个包含多列的 pandas 数据框。目的是在其中一列中找到唯一值。
实现此目的的两种方法是:
获取该系列的集合列表:list(set(data['Day']))
使用 pandas 的函数获取唯一值 data['Day'].unique()
在我的试验中,set
方法工作得更快。大多数情况下都是这样吗?为什么,为什么不呢?任何其他资源利用影响?
还请添加其中一个效果更好的原因。
这取决于数据类型。对于数字类型,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)
结果似乎与唯一条目的数量有很大差异:
这是对 ipl 数据集(交付)的一些时间测试
对于具有 577 个唯一 ID 的列 match_id:unique() 似乎非常有效
%timeit list(set(deliveries['match_id']))
27.5 ms ± 2.09 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit deliveries['match_id'].unique()
1.79 ms ± 322 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
对于包含 13 个独特团队的 batting_team 列:此处的 list(set()) 稍好一些
%timeit list(set(deliveries['batting_team']))
9.92 ms ± 945 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit deliveries['batting_team'].unique()
10.2 ms ± 315 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
编辑:尝试测试弦理论。 运行 对具有 436 个唯一条目的字符串列 batsman 进行相同测试
%timeit list(set(deliveries['batsman']))
9.32 ms ± 431 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit deliveries['batsman'].unique()
8.06 ms ± 110 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
对具有很少唯一值的列使用分类数据类型是有意义的。
演示:
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)
1M 行的时间几乎相同
让我们测试类别数据类型:
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)
更新: 1.000.000 行中有 500 个唯一值 DF:
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)
结论:在你的真实数据上"timeit"总是更好——你可能会有不同的结果...
我有一个包含多列的 pandas 数据框。目的是在其中一列中找到唯一值。
实现此目的的两种方法是:
获取该系列的集合列表:
list(set(data['Day']))
使用 pandas 的函数获取唯一值
data['Day'].unique()
在我的试验中,set
方法工作得更快。大多数情况下都是这样吗?为什么,为什么不呢?任何其他资源利用影响?
还请添加其中一个效果更好的原因。
这取决于数据类型。对于数字类型,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)
结果似乎与唯一条目的数量有很大差异:
这是对 ipl 数据集(交付)的一些时间测试
对于具有 577 个唯一 ID 的列 match_id:unique() 似乎非常有效
%timeit list(set(deliveries['match_id']))
27.5 ms ± 2.09 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit deliveries['match_id'].unique()
1.79 ms ± 322 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
对于包含 13 个独特团队的 batting_team 列:此处的 list(set()) 稍好一些
%timeit list(set(deliveries['batting_team']))
9.92 ms ± 945 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit deliveries['batting_team'].unique()
10.2 ms ± 315 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
编辑:尝试测试弦理论。 运行 对具有 436 个唯一条目的字符串列 batsman 进行相同测试
%timeit list(set(deliveries['batsman']))
9.32 ms ± 431 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit deliveries['batsman'].unique()
8.06 ms ± 110 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
对具有很少唯一值的列使用分类数据类型是有意义的。
演示:
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)
1M 行的时间几乎相同
让我们测试类别数据类型:
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)
更新: 1.000.000 行中有 500 个唯一值 DF:
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)
结论:在你的真实数据上"timeit"总是更好——你可能会有不同的结果...