我有一个项目进度表中的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有10000行,但可以扩展。
有什么建议吗?
答案 0 :(得分:0)
这始终是必需的循环,因为使用每行范围。一种可能的解决方案是将DataFrame.itertuples
与concat
和sum
一起使用:
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