我试图为分组滚动窗口创建一个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+行,几分钟后我就放弃了。
有没有人有更快的解决方案?
1条答案
按热度按时间zsohkypk1#
使用parallel-pandas可以轻松实现快速执行。
第一个
对于10,000行代码,在我的PC上使用非并行应用方法需要不到1秒的时间,而使用非并行应用方法需要7秒。