Python Pandas-每天dateranges的总和值
我有一个来自项目进度表的数据框架:Python Pandas-每天dateranges的总和值,python,pandas,Python,Pandas,我有一个来自项目进度表的数据框架: 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-
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()
day=timedelta(days=1)
新行=[]
对于索引,df.iterrows()中的行:
开始=行。开始
虽然start这里总是需要循环,因为处理每行的范围。一种可能的解决方案是使用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
这里总是有必要的循环,因为使用每行的范围。一种可能的解决方案是使用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
顺便说一句,我对否决票有点惊讶——因为我的意见是一个很好的问题——数据、预期输出、代码和操作尝试。顺便说一句,对downvote有点惊讶-因为我的意见是一个很好的问题-数据,预期输出,代码什么OP尝试。没有理由投反对票。谢谢,这很有效,而且速度很快。如果有传统的专栏,哪一个最好去?比如说,您想将所有其他数据保留在一行中吗?我也尝试过我的解决方案,但没有成功。@所有行的Nanuq都可能是解决方案的第一部分-如果需要,创建默认索引(如果需要),请为df.itertuple()中的r创建默认索引。重置\u index(drop=True)
然后为df.itertuple()中的r创建df1=(pd.concat([pd.Series(r.index,pd.date\u range(r.Start,r.End))).rename_axis('day')。reset_index(name='idx')。join(df,on='idx')。drop('idx',axis=1))print(df1)
然后如果每个列聚合函数都需要聚合,如df1=df1.groupby('day',as_index=False)。agg({'Task':'first',Staff':'sum'))
,以避免丢失columnperfect。工作非常快。谢谢,谢谢,这很有效,而且速度很快。如果有传统的专栏,哪一个最好去?比如说,您想将所有其他数据保留在一行中吗?我也用.itertuples()
尝试了我的解决方案,但没有成功。@所有行的nanuuq可能是解决方案的第一部分-必要时创建默认索引df=df.reset\u index(drop=True)
然后df1=(pd.concat([pd.Series(r.index,pd.date\u range(r.Start,r.End)),用于df.itertuples()])).rename_axis('day')。reset_index(name='idx')。join(df,on='idx')。drop('idx',axis=1))print(df1)
然后如果每个列聚合函数都需要聚合,如df1=df1.groupby('day',as_index=False)。agg({'Task':'first',Staff':'sum'))
,以避免丢失columnperfect。工作非常快。谢谢