我正在将我们的一些旧代码从R转换到python。在这个过程中,我发现熊猫比R慢一点。我有兴趣知道我是否做错了什么。
R代码(在我的系统上大约需要2毫秒):
df = data.frame(col_a = sample(letters[1:3],20,T),
col_b = sample(1:2,20,T),
col_c = sample(letters[1:2],20,T),
col_d = sample(c(4,2),20,T)
)
microbenchmark::microbenchmark(
a = df %>%
group_by(col_a, col_b) %>%
summarise(
a = sum(col_c == 'a'),
b = sum(col_c == 'b'),
c = a/b
) %>%
ungroup()
)
pandas (在我的系统上运行10ms ):
df = pd.DataFrame({
'col_a': np.random.choice(['a','b','c'],N),
'col_b': np.random.choice([1,2],N),
'col_c': np.random.choice(['a', 'b'],N),
'col_d': np.random.choice(['4', '2'],N),
})
%%timeit
df1 = df.groupby(['col_a', 'col_b']).agg({
'col_c':[
('a',lambda x: (x=='a').sum()),
('b',lambda x: (x=='b').sum())
]}).reset_index()
df1['rat'] = df1.col_c.a/df1.col_c.b
发布于 2019-06-03 09:19:51
这不是一个技术答案,但值得注意的是,在Pandas中有许多不同的方法来完成此操作,其中一些方法比其他方法更快。例如,下面的Pandas代码在大约5毫秒内获得了您正在寻找的值(尽管有一些丑陋的MultiIndex列):
df.groupby(['col_a', 'col_b', 'col_c'])\
.count()\
.unstack()\
.assign(rat = lambda x: x.col_d.a/x.col_d.b)
4.96 ms ± 169 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
除了底层的速度提升之外,我认为tidyverse
语法相对于Pandas语法的主要速度优势在于,summarise()
将使每个新变量在同一调用中立即可用,这避免了必须spread
计数然后计算rat
。
如果在Pandas中有类似的东西,我不知道。最接近的是pipe()
或在assign()
中使用lambda
。链中的每个新函数调用都需要时间来执行,因此Pandas最终会变得更慢。
https://stackoverflow.com/questions/56419400
复制相似问题