pandas 通过利用多列滚动应用加快分组速度

gzszwxb4  于 2022-11-27  发布在  其他
关注(0)|答案(1)|浏览(133)

我试图为分组滚动窗口创建一个Brier Score。由于计算Brier Score的函数使用分组滚动窗口中的多列,我不得不使用here作为一个相当笨拙的解决方案的基础:

import pandas as pd
import numpy as np
from pandas._libs.tslibs.timestamps import Timestamp
import random

ROWS = 20

# create dataframe

def create_random_dates(start: Timestamp, end: Timestamp, n: int): 
    divide_by = 24*60*60*10**9
    start_u = start.value // divide_by
    end_u = end.value // divide_by
    return pd.to_datetime([random.randint(start_u, end_u) for p in range(n)], unit="D") 

random.seed(1)
start = pd.to_datetime('2015-01-01')
end = pd.to_datetime('2018-01-01')
random_dates = create_random_dates(start, end, ROWS)
df = pd.DataFrame(
    {
        "id_": list(range(ROWS)),
        "date": random_dates,
        "group": [random.randint(1, 2) for p in range(ROWS)],
        "y_true": [random.randint(0, 1) for p in range(ROWS)],
        "y_prob": [random.random() for p in range(ROWS)],
    }
)
df.sort_values(["group", "date"], inplace=True)
df.reset_index(drop=True, inplace=True)
df.reset_index(inplace=True)

# calculate brier score

def calc_brier(series: pd.Series, df: pd.DataFrame) -> float:
    df_group = df.loc[series.values]
    return np.average((df_group["y_true"].values - df_group["y_prob"].values) ** 2)

df_date_idx = df.set_index("date")
df_date_idx.drop(["id_", "y_true", "y_prob"], axis=1, inplace=True)
brier: pd.DataFrame = (
    df_date_idx
    .groupby("group", as_index=False)
    .rolling("1000d", min_periods=3, closed="left")
    .apply(calc_brier, args=(df, ))
)
df.drop("index", axis=1, inplace=True)
df["brier"] = brier["index"].values
df

这在行数较少的情况下工作得很好,但一旦我开始扩展ROWS,就需要一段时间。在我的实际用例中, Dataframe 是1m+行,几分钟后我就放弃了。
有没有人有更快的解决方案?

zsohkypk

zsohkypk1#

使用parallel-pandas可以轻松实现快速执行。
第一个
对于10,000行代码,在我的PC上使用非并行应用方法需要不到1秒的时间,而使用非并行应用方法需要7秒。

相关问题