繁体   English   中英

通过列值(Python pandas)在DataFrame切片上查找计算函数的最快方法

[英]Fastest way to find compute function on DataFrame slices by column value (Python pandas)

我试图在数据框上创建一个列,其中包含列A(值列)的最小值,列B(id列)具有特定值。 我的代码很慢。 我正在寻找一种更快的方法来做到这一点。 这是我的小功能:

def apply_by_id_value(df, id_col="id_col", val_col="val_col", offset_col="offset", f=min):
    for rid in set(df[id_col].values):
        df.loc[df[id_col] == rid, offset_col] =  f(df[df[id_col] == rid][val_col])
    return df

示例用法:

import pandas as pd
import numpy as np
# create data frame
df = pd.DataFrame({"id_col":[0, 0, 0, 1, 1, 1, 2, 2, 2], 
                   "val_col":[0.1, 0.2, 0.3, 0.6, 0.4, 0.5, 0.2, 0.1, 0.0]})

print df.head(10)
# output
   id_col  val_col
0       0      0.1
1       0      0.2
2       0      0.3
3       1      0.6
4       1      0.4
5       1      0.5
6       2      0.2
7       2      0.1
8       2      0.0

df = apply_by_id_value(df)
print df.head(10) 
# output

   id_col  val_col  offset
0       0      0.1     0.1
1       0      0.2     0.1
2       0      0.3     0.1
3       1      0.6     0.4
4       1      0.4     0.4
5       1      0.5     0.4
6       2      0.2     0.0
7       2      0.1     0.0
8       2      0.0     0.0

更多上下文:在我的实际数据中,“id_col”列有大约30000个或更多的唯一值。 这意味着数据帧必须切片30000次。 我想这是瓶颈。

在'id_col'上执行groupby ,然后执行transform传递函数'min',这将返回与原始df对齐的Series,以便您可以添加为新列:

In [13]:

df = pd.DataFrame({"id_col":[0, 0, 0, 1, 1, 1, 2, 2, 2], 
                   "val_col":[0.1, 0.2, 0.3, 0.6, 0.4, 0.5, 0.2, 0.1, 0.0]})
df['offset'] = df.groupby('id_col').transform('min')
df
Out[13]:
   id_col  val_col  offset
0       0      0.1     0.1
1       0      0.2     0.1
2       0      0.3     0.1
3       1      0.6     0.4
4       1      0.4     0.4
5       1      0.5     0.4
6       2      0.2     0.0
7       2      0.1     0.0
8       2      0.0     0.0

计时

In [15]:

def apply_by_id_value(df, id_col="id_col", val_col="val_col", offset_col="offset", f=min):
    for rid in set(df[id_col].values):
        df.loc[df[id_col] == rid, offset_col] =  f(df[df[id_col] == rid][val_col])
    return df
%timeit apply_by_id_value(df)
%timeit df.groupby('id_col').transform('min')
100 loops, best of 3: 8.12 ms per loop
100 loops, best of 3: 5.99 ms per loop

因此groupbytransform在这个数据集上更快,我希望它在你的真实数据集上明显更快,因为它会更好地扩展。

对于800,000行df,我得到以下时间:

1 loops, best of 3: 611 ms per loop
1 loops, best of 3: 438 ms per loop

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM