Python 分组并减去大熊猫的第一次出现和最后一次出现
我在熊猫中有以下数据帧Python 分组并减去大熊猫的第一次出现和最后一次出现,python,pandas,Python,Pandas,我在熊猫中有以下数据帧 code date time dip flag tank qty 123 2018-12-23 08:00:00 389 0 1 1300 123 2018-12-23 09:00:00 380 0 1 1250 123 2018-12-23 10:00:00 378 0 1
code date time dip flag tank qty
123 2018-12-23 08:00:00 389 0 1 1300
123 2018-12-23 09:00:00 380 0 1 1250
123 2018-12-23 10:00:00 378 0 1 1200
123 2018-12-23 11:00:00 345 1 1 1150
123 2018-12-23 12:00:00 342 1 1 1100
123 2018-12-23 13:00:00 340 1 1 1050
123 2018-12-23 14:00:00 338 1 1 1000
123 2018-12-23 15:00:00 380 0 1 1500
123 2018-12-23 16:00:00 340 1 1 1000
123 2018-12-23 17:00:00 340 1 1 1000
123 2018-12-23 08:00:00 389 0 2 1300
123 2018-12-23 09:00:00 380 0 2 1250
123 2018-12-23 10:00:00 378 0 2 1200
123 2018-12-23 11:00:00 345 1 2 1150
123 2018-12-23 12:00:00 342 1 2 1100
123 2018-12-23 13:00:00 340 1 2 1050
123 2018-12-23 14:00:00 338 1 2 1000
我想知道多少次dip
低于350,直到什么时候(以小时为单位)保持在350以下,以及低于350时的销售量是多少
下面是我想要的数据帧。当倾角小于350时,我已经将标志设置为1
code date tank frequency qty_sold time
123 2018-12-23 1 4 150 3
123 2018-12-23 2 4 150 3
我可以通过groupby找到频率。需要帮忙找另外两个吗
df_agg= df.groupby(['code','date','tank']).agg({'flag':['sum']}).reset_index()
你可以做:
# to get till what time (hour)
df.loc[df['dip'].lt(350),'time'].dt.hour.max()
# what is the quantity sold
df.loc[df['dip'].lt(350),'qty'].sum()
使用:
只有一个问题,如果有多个问题中编辑的小于350的标志实例,该怎么办。这个答案仍然正确吗?现在,在这个问题中,350以下的实例是11:00-14:00和16:00-17:00,在一个解决方案中,我们使用第一个和最后一个条目。@Neil-是的,它是这样工作的-首先通过
df[df['dip']<350]
过滤,所以获得350以下的所有行。然后,如果有多组日期时间(如编辑答案中所示),则第一组和最后一组的日期时间使用第一组的第一个日期时间(11:00),最后一组的最后一个日期时间使用最后一个日期时间(17:00)。所以差异是不正确的,因为17:00-11:00也计算不在组中的日期时间(14:00到16:00)。所以答案必须改变,请给我一些时间,如果我的时间频率是半小时呢?我可以将您的代码编辑为pd.Timedelta(0.5,'H')
?
#create datetimes column
df['datetime'] = pd.to_datetime(df['date'] + ' ' + df['time'])
#add aggregation by first and last
df_agg= df[df['dip'] < 350].groupby(['code','date','tank']).agg({'flag':['sum'],
'datetime':['first','last'],
'qty':['first','last']})
#flatten MultiIndex
df_agg.columns = df_agg.columns.map('_'.join)
#substract columns, timedeltas convert to hours
df_agg['qty_sold'] = df_agg.pop('qty_first') - df_agg.pop('qty_last')
df_agg['time'] = (df_agg.pop('datetime_last') - df_agg.pop('datetime_first'))
.dt.total_seconds().div(3600).astype(int)
#rename column and create default index
df_agg = df_agg.rename(columns={'flag_size':'frequency'}).reset_index()
print (df_agg)
code date tank flag_sum qty_sold time
0 123 2018-12-23 1 4 150 3
1 123 2018-12-23 2 4 150 3
df['datetime'] = pd.to_datetime(df['date'] + ' ' + df['time'])
df_agg= df[df['dip'] < 350].copy()
df_agg['g'] = (df_agg.groupby(['code','date','tank'])['datetime'].diff()
.ne(pd.Timedelta(1, 'H'))
.cumsum())
df_agg= df_agg.groupby(['code','date','tank','g']).agg({'flag':['sum'],
'datetime':['first','last'],
'qty':['first','last']})
df_agg.columns = df_agg.columns.map('_'.join)
df_agg['qty_sold'] = df_agg.pop('qty_first') - df_agg.pop('qty_last')
df_agg['time'] = ((df_agg.pop('datetime_last') - df_agg.pop('datetime_first'))
.dt.total_seconds().div(3600).astype(int))
df_agg = (df_agg.rename(columns={'flag_size':'frequency'})
.sum(level=[0,1,2])
.reset_index()
)
print (df_agg)
code date tank flag_sum qty_sold time
0 123 2018-12-23 1 6 150 4
1 123 2018-12-23 2 4 150 3