使用 Python/Pandas 获取任何特定日期的未完成任务数量
Get the amount of open tasks for any specific date with Python/Pandas
我有一个包含开始和结束日期的任务列表,我需要知道我在特定的一天有多少未完成的任务。
我目前的解决方案是与日历交叉连接 table:
import pandas as pd
df = pd.DataFrame({
'ID': [101, 102, 103],
'Start' : ['01.01.2022', '02.01.2022', '03.01.2022'],
'End' : ['03.01.2022', '08.01.2022', '05.01.2022']
})
df['Start'] = pd.to_datetime(df['Start'], format="%d.%m.%Y")
df['Ende'] = pd.to_datetime(df['End'], format="%d.%m.%Y")
calender = pd.DataFrame({
'Day': pd.date_range(start=df['Start'].min(), end=df['End'].max())
})
df = pd.merge(left=df, right=calender, how='cross')
df = df.loc[(df['Day'] >= df['Start']) & (df['Day'] <= df['End'])]
df.pivot_table(index='Day', aggfunc='count', values='ID')
此解决方案适用于一小部分数据,但我的原始数据有 50 万个项目,而日历帮助table 有 2 千个项目。所以交叉连接导致 10 亿行,这似乎非常低效并且减慢了系统速度。
pandas有没有更好的方法来解决这个问题?
您可以使用 .apply
来调用将 DateTimeIndex
的范围增加 1
的函数。例如:
df = pd.DataFrame(
{
"ID": [101, 102, 103],
"Start": ["01.01.2022", "02.01.2022", "03.01.2022"],
"End": ["03.01.2022", "08.01.2022", "05.01.2022"],
}
)
df["Start"] = pd.to_datetime(df["Start"], format="%d.%m.%Y")
df["End"] = pd.to_datetime(df["End"], format="%d.%m.%Y")
out = pd.DataFrame(
{"Num Tasks": 0},
index=pd.date_range(start=df["Start"].min(), end=df["End"].max()),
)
def increase_tasks(row):
out.loc[row["Start"] : row["End"]] += 1
df.apply(increase_tasks, axis=1)
print(out)
打印:
Num Tasks
2022-01-01 1
2022-01-02 2
2022-01-03 3
2022-01-04 2
2022-01-05 2
2022-01-06 1
2022-01-07 1
2022-01-08 1
我有一个包含开始和结束日期的任务列表,我需要知道我在特定的一天有多少未完成的任务。
我目前的解决方案是与日历交叉连接 table:
import pandas as pd
df = pd.DataFrame({
'ID': [101, 102, 103],
'Start' : ['01.01.2022', '02.01.2022', '03.01.2022'],
'End' : ['03.01.2022', '08.01.2022', '05.01.2022']
})
df['Start'] = pd.to_datetime(df['Start'], format="%d.%m.%Y")
df['Ende'] = pd.to_datetime(df['End'], format="%d.%m.%Y")
calender = pd.DataFrame({
'Day': pd.date_range(start=df['Start'].min(), end=df['End'].max())
})
df = pd.merge(left=df, right=calender, how='cross')
df = df.loc[(df['Day'] >= df['Start']) & (df['Day'] <= df['End'])]
df.pivot_table(index='Day', aggfunc='count', values='ID')
此解决方案适用于一小部分数据,但我的原始数据有 50 万个项目,而日历帮助table 有 2 千个项目。所以交叉连接导致 10 亿行,这似乎非常低效并且减慢了系统速度。
pandas有没有更好的方法来解决这个问题?
您可以使用 .apply
来调用将 DateTimeIndex
的范围增加 1
的函数。例如:
df = pd.DataFrame(
{
"ID": [101, 102, 103],
"Start": ["01.01.2022", "02.01.2022", "03.01.2022"],
"End": ["03.01.2022", "08.01.2022", "05.01.2022"],
}
)
df["Start"] = pd.to_datetime(df["Start"], format="%d.%m.%Y")
df["End"] = pd.to_datetime(df["End"], format="%d.%m.%Y")
out = pd.DataFrame(
{"Num Tasks": 0},
index=pd.date_range(start=df["Start"].min(), end=df["End"].max()),
)
def increase_tasks(row):
out.loc[row["Start"] : row["End"]] += 1
df.apply(increase_tasks, axis=1)
print(out)
打印:
Num Tasks
2022-01-01 1
2022-01-02 2
2022-01-03 3
2022-01-04 2
2022-01-05 2
2022-01-06 1
2022-01-07 1
2022-01-08 1