gpt4 book ai didi

python - 如何在保持形状和索引的同时(快速)获得 DataFrame 的第一个非 Nan 每日值?

转载 作者:行者123 更新时间:2023-12-03 23:38:18 25 4
gpt4 key购买 nike

我有以下 pd.DataFrame

from datetime import datetime
df1 = pd.DataFrame(
data=[[0, 0, 1], [0, 1, 1], [1, 1, 0], [1, 1, 0], [0, 0, 1], [0, 1, 1], [1, 1, 0], [1, 1, 0]],
index=[
datetime(2020, 1, 1, 1, 10), datetime(2020, 1, 1, 1, 15), datetime(2020, 1, 1, 1, 20), datetime(2020, 1, 1, 1, 25),
datetime(2020, 1, 2, 1, 10), datetime(2020, 1, 2, 1, 15), datetime(2020, 1, 2, 1, 20), datetime(2020, 1, 2, 1, 25)
]
)
我想将其转换为以下形式:
df2 = pd.DataFrame(
data=[[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 0, 0], [0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 0, 0]],
index=[
datetime(2020, 1, 1, 1, 10), datetime(2020, 1, 1, 1, 15), datetime(2020, 1, 1, 1, 20), datetime(2020, 1, 1, 1, 25),
datetime(2020, 1, 2, 1, 10), datetime(2020, 1, 2, 1, 15), datetime(2020, 1, 2, 1, 20), datetime(2020, 1, 2, 1, 25)
]
)
我设法通过以下方式实现了这一目标:
df3 = pd.concat([df1[col].loc[df1[col].replace(0, np.nan).groupby(df1.index.date).idxmax()].dropna().reindex(df1.index) for col in df1.columns], axis=1).replace(np.nan, 0).astype(int)
使得 df2.equals(df3)评估为 True。
我的问题是我的方式对于大型 pd.DataFrame 来说很慢我想知道如何让它更快?

最佳答案

一种解决方案:
只需获取每行的前 1 个值:

df1[df1.cumsum(axis=1)!=1] = 0
设置一个临时日期 col
df1["date"] = df1.index.date
将任何重复的行设置为 0
df1[df1.duplicated()] = 0
去掉临时日期列
df1.drop("date", axis=1, inplace=True)
这大约使我的 PC 上的运行时间减少了一半:
对于 100 个循环:
提问方式:7.292934599994624s
方法一:0.3330558000016026s
不创建临时日期列可能会进行一些优化,但我不确定如何执行此操作。希望有更多 Pandas 知识的人可以告诉我!
此代码还假定数据已按日期排序
import pandas as pd
from datetime import datetime
import numpy as np
import timeit

n = 200

data = [[0, 0, 1], [0, 1, 1], [1, 1, 0], [1, 1, 0]]*n
index = [[datetime(y, 1, 1, 1, x) for x in [10, 15, 20, 25]] for y in range(2020, 2020+n)]
index = [item for sublist in index for item in sublist]

df1 = pd.DataFrame(
data=data,
index=index
)

def method1(df):
return pd.concat([df[col].loc[df[col].replace(0, np.nan).groupby(df.index.date).idxmax()].dropna().reindex(df.index) for col in df.columns], axis=1).replace(np.nan, 0).astype(int)

def method2(df):
df3 = df.copy()
df3[df3.cumsum(axis=1)!=1] = 0
df3["date"] = df3.index.date
df3[df3.duplicated()] = 0
df3.drop("date", axis=1, inplace=True)
return df3

start = timeit.default_timer()
for i in range(100):
new_df = method1(df1)
end = timeit.default_timer()
print(end-start)

start = timeit.default_timer()
for i in range(100):
new_df = method2(df1)
end = timeit.default_timer()
print(end-start)

关于python - 如何在保持形状和索引的同时(快速)获得 DataFrame 的第一个非 Nan 每日值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68099745/

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