gpt4 book ai didi

python - Pandas 填补了性能问题

转载 作者:太空宇宙 更新时间:2023-11-03 11:48:50 26 4
gpt4 key购买 nike

我有一个带有多索引(Date、InputTime)的数据框,这个数据框可能在列(Value、Id)中包含一些 NA 值。我想填写远期值(value),但仅按日期填写,而且我发现无论如何都无法以非常有效的方式做到这一点。

这是我拥有的数据框类型:

Dataframe example

这是我想要的结果:

Dataframe properly fill forward by date only

因此,为了按日期正确回填,我可以使用 groupby(level=0) 函数。 groupby 很快,但是按日期分组应用于数据框的填充函数真的太慢了​​。

这是我用来比较简单前向填充(它没有给出预期结果但运行速度非常快)和预期按日期前向填充(它给出预期结果但速度太慢)的代码。

import numpy as np
import pandas as pd
import datetime as dt

# Show pandas & numpy versions
print('pandas '+pd.__version__)
print('numpy '+np.__version__)

# Build a big list of (Date,InputTime,Value,Id)
listdata = []
d = dt.datetime(2001,10,6,5)
for i in range(0,100000):
listdata.append((d.date(), d, 2*i if i%3==1 else np.NaN, i if i%3==1 else np.NaN))
d = d + dt.timedelta(hours=8)

# Create the dataframe with Date and InputTime as index
df = pd.DataFrame.from_records(listdata, index=['Date','InputTime'], columns=['Date', 'InputTime', 'Value', 'Id'])

# Simple Fill forward on index
start = dt.datetime.now()
for col in df.columns:
df[col] = df[col].ffill()
end = dt.datetime.now()
print "Time to fill forward on index = " + str((end-start).total_seconds()) + " s"

# Fill forward on Date (first level of index)
start = dt.datetime.now()
for col in df.columns:
df[col] = df[col].groupby(level=0).ffill()
end = dt.datetime.now()
print "Time to fill forward on Date only = " + str((end-start).total_seconds()) + " s"

Results

有人能解释一下为什么这段代码这么慢,或者能帮我找到一种在大数据帧上按日期向前填充的有效方法吗?

谢谢

最佳答案

github/jreback:这是#7895 的骗局。 .ffill 没有在 cython 中的 groupby 操作中实现(尽管它肯定可以),而是在每个组上调用 python 空间。这是一个简单的方法来做到这一点。网址:https://github.com/pandas-dev/pandas/issues/11296

根据 jreback 的回答,当你执行 groupby 时,ffill() 没有优化,但 cumsum() 是。试试这个:

df = df.sort_index()
df.ffill() * (1 - df.isnull().astype(int)).groupby(level=0).cumsum().applymap(lambda x: None if x == 0 else 1)

效用函数:(归功于@Phun)

def ffill_se(df: pd.DataFrame, group_cols: List[str]):
df['GROUP'] = df.groupby(group_cols).ngroup()
df.set_index(['GROUP'], inplace=True)
df.sort_index(inplace=True)
df = df.ffill() * (1 - df.isnull().astype(int)).groupby(level=0).cumsum().applymap(lambda x: None if x == 0 else 1)
df.reset_index(inplace=True, drop=True)
return df

关于python - Pandas 填补了性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33019877/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com