python - Pandas - 每天日期范围内的值总和

标签 python pandas

我有一个来自项目计划的 DataFrame:

Task    Start        End      Staff
Task 1  2020-1-1    2020-1-4   11
Task 2  2020-1-2    2020-1-4   12
Task 3  2020-1-4    2020-1-6    2
...

期望的输出:

day         staff
2020-1-1    11
2020-1-2    23
2020-1-3    23
2020-1-4    25
2020-1-5    14

到目前为止,我正在使用 .iterrows() 来遍历完整的 df。

day = timedelta(days=1)
new_rows = []
for index, row in df.iterrows():
    start = row.Start
    while start <= row.End:
        newrow = row.copy()
        newrow['day'] = start
        new_rows.append(newrow.values)

        start += day
df_staff = pd.DataFrame(new_rows, columns= newrow.index).reset_index()

效果很好,只是想知道是否有更好/更快的方法。现在,我的 df 有 10 000 行,但可以扩展。

有什么建议吗?

最佳答案

这里总是有必要的循环,因为要处理每行的范围。一种可能的解决方案是使用 DataFrame.itertuples使用concatsum:

df1 = (pd.concat([pd.Series(r.Staff,pd.date_range(r.Start, r.End)) 
                   for r in df.itertuples()])
         .sum(level=0)
         .rename_axis('day')
         .reset_index(name='staff'))
print (df1)
         day  staff
0 2020-01-01     11
1 2020-01-02     23
2 2020-01-03     23
3 2020-01-04     25
4 2020-01-05      2
5 2020-01-06      2

另一个具有列表理解的解决方案:

zipped = zip(df.Start, df.End, df.Staff)

df1 = (pd.DataFrame([(x, v) for s, e, v in zipped for x in pd.date_range(s, e)], 
                    columns=['day','staff'])
        .groupby('day', as_index=False)['staff'].sum())

print (df1)
         day  staff
0 2020-01-01     11
1 2020-01-02     23
2 2020-01-03     23
3 2020-01-04     25
4 2020-01-05      2
5 2020-01-06      2

关于python - Pandas - 每天日期范围内的值总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59116478/

相关文章:

python - 使用 __contains__ 对 numpy 数组进行非常缓慢的迭代

python - 如何计算分组 df 的差异?

矩阵的 Python Scipy spearman 相关性与双数组相关性不匹配,也不匹配 pandas.Data.Frame.corr()

python - 从 pandas 数据框中选择带有日期的行

python - 从 Pandas DataFrame 中删除列表

python - 确定 lambda 函数中调用的方法

python - Scipy - 使用球面贝塞尔函数时出错

Python 自引用 for 循环

python - 将方法动态添加到类_而不_在python中公开方法

python - 你如何在 Pandas 中合并 2 个系列