Python 如果在某些时间/值之间,则为累积和
我想在Python 如果在某些时间/值之间,则为累积和,python,pandas,loops,cumulative-sum,Python,Pandas,Loops,Cumulative Sum,我想在final_df中插入一个名为total的新列,如果它发生在final_df中的两个时间之间,则它是df中值的累积和。如果值出现在final_df中的开始和结束之间,则它对值进行求和。例如,在final_df的01:30到02:00的时间范围内,df中的索引0和1都出现在这个时间范围内,因此总数为15(10+5) 我有两个数据帧: df import pandas as pd d = {'start_time': ['01:00','00:00','00:30','02:00'],
final_df
中插入一个名为total
的新列,如果它发生在final_df
中的两个时间之间,则它是df
中值的累积和。如果值出现在final_df
中的开始
和结束
之间,则它对值进行求和。例如,在final_df
的01:30到02:00的时间范围内,df
中的索引0和1都出现在这个时间范围内,因此总数为15(10+5)
我有两个数据帧:
df
import pandas as pd
d = {'start_time': ['01:00','00:00','00:30','02:00'],
'end_time': ['02:00','03:00','01:30','02:30'],
'value': ['10','5','20','5']}
df = pd.DataFrame(data=d)
final_df = {'start_time': ['00:00, 00:30, 01:00, 01:30, 02:00, 02:30'],
'end_time': ['00:30, 01:00, 01:30, 02:00, 02:30, 03:00']}
final_df = pd.DataFrame(data=final_d)
start_time end_time total
00:00 00:30 5
00:30 01:00 25
01:00 01:30 35
01:30 02:00 15
02:30 03:00 10
final_df
import pandas as pd
d = {'start_time': ['01:00','00:00','00:30','02:00'],
'end_time': ['02:00','03:00','01:30','02:30'],
'value': ['10','5','20','5']}
df = pd.DataFrame(data=d)
final_df = {'start_time': ['00:00, 00:30, 01:00, 01:30, 02:00, 02:30'],
'end_time': ['00:30, 01:00, 01:30, 02:00, 02:30, 03:00']}
final_df = pd.DataFrame(data=final_d)
start_time end_time total
00:00 00:30 5
00:30 01:00 25
01:00 01:30 35
01:30 02:00 15
02:30 03:00 10
输出我想要最终的_df
import pandas as pd
d = {'start_time': ['01:00','00:00','00:30','02:00'],
'end_time': ['02:00','03:00','01:30','02:30'],
'value': ['10','5','20','5']}
df = pd.DataFrame(data=d)
final_df = {'start_time': ['00:00, 00:30, 01:00, 01:30, 02:00, 02:30'],
'end_time': ['00:30, 01:00, 01:30, 02:00, 02:30, 03:00']}
final_df = pd.DataFrame(data=final_d)
start_time end_time total
00:00 00:30 5
00:30 01:00 25
01:00 01:30 35
01:30 02:00 15
02:30 03:00 10
我的尝试
final_df['total'] = final_df.apply(lambda x: df.loc[(df['start_time'] >= x.start_time) &
(df['end_time'] <= x.end_time), 'value'].sum(), axis=1)
但我不想转换成datetime。有办法解决这个问题吗
问题2
这笔钱用得不好。它只是寻找时间范围的精确匹配。因此,输出为:
start_time end_time total
00:00 00:30 0
00:30 01:00 0
01:00 01:30 0
01:30 02:00 0
02:30 03:00 5
不使用apply
的一种方法可能是这样的
df_ = (df.rename(columns={'start_time':1, 'end_time':-1}) #to use in the calculation later
.rename_axis(columns='mult') # mostly for esthetic
.set_index('value').stack() #reshape the data
.reset_index(name='time') # put the index back to columns
)
df_ = (df_.set_index(pd.to_datetime(df_['time'], format='%H:%M')) #to use resampling technic
.assign(total=lambda x: x['value'].astype(float)*x['mult']) #get plus or minus the value depending start/end
.resample('30T')[['total']].sum() # get the sum at the 30min bounds
.cumsum() #cumulative sum from the beginning
)
# create the column for merge with final resul
df_['start_time'] = df_.index.strftime('%H:%M')
# merge
final_df = final_df.merge(df_)
你得到了什么
print (final_df)
start_time end_time total
0 00:00 00:30 5.0
1 00:30 01:00 25.0
2 01:00 01:30 35.0
3 01:30 02:00 15.0
4 02:00 02:30 10.0
5 02:30 03:00 5.0
但如果要使用apply,首先需要确保列是良好的数据类型,然后按相反的顺序执行不平等性,如:
df['start_time'] = pd.to_datetime(df['start_time'], format='%H:%M')
df['end_time'] = pd.to_datetime(df['end_time'], format='%H:%M')
df['value'] = df['value'].astype(float)
final_df['start_time'] = pd.to_datetime(final_df['start_time'], format='%H:%M')
final_df['end_time'] = pd.to_datetime(final_df['end_time'], format='%H:%M')
final_df.apply(
lambda x: df.loc[(df['start_time'] <= x.start_time) & #see other inequality
(df['end_time'] >= x.end_time), 'value'].sum(), axis=1)
0 5.0
1 25.0
2 35.0
3 15.0
4 10.0
5 5.0
dtype: float64
df['start\u time']=pd.to\u datetime(df['start\u time'],格式=“%H:%M”)
df['end\u time']=pd.to\u datetime(df['end\u time'],格式=“%H:%M”)
df['value']=df['value'].aType(浮点)
final_df['start_time']=pd.to_datetime(final_df['start_time'],格式=“%H:%M”)
final_df['end_time']=pd.to_datetime(final_df['end_time'],格式=“%H:%M”)
最终应用(
lambda x:df.loc[(df['start\u time']=x.end\u time),'value'].sum(),轴=1)
0 5.0
1 25.0
2 35.0
3 15.0
4 10.0
5 5.0
数据类型:64
Nice answer@Ben.T.Nice answer,两种解决方案都有效。对于应用解决方案,由于某种原因,我的最终_df中的最后一个时间范围(即23:30到00:00。注意,上面没有包括我的样本)总结了列中不应该出现的所有内容。@thor-hmm这样我不确定为什么,我将尝试测试一些东西,但可能出现边界效应,特别是在玩间歇时:)@thor所以在考虑了一下你的评论之后,你得到所有的总和是有意义的,就像这样,我不确定有没有一个简单的解决方法。如果你用这个时间间隔写出不等式,那么你会得到(df['start_time']=00:00),它给出了df中的所有值。