Пытаясь сократить свой код, я заметил, что мне часто приходится группировать, а затем присоединять сгруппированный фрейм данных к родительскому. Есть ли способы написать более элегантный и лаконичный код? Пожалуйста, проверьте мой пример ниже:
Предположим, что этот родительский фрейм данных: (вы можете копировать и вставлять для воспроизведения)
chem_1=np.array([-5, 9, -1,4,-2,3,4,np.nan,np.nan,np.nan,8,np.nan,9])
chem_2=np.array([6, -1, -4,np.nan,-7,-5,5,np.nan,10,-9,8,6,np.nan])
frame_total=pd.DataFrame(list(zip(chem_1,chem_2)), columns=['chem_1', 'chem_2'])
frame_total['sum_hourly']=frame_total.sum(axis=1)
frame_total.loc[frame_total[['chem_1', 'chem_2']].isnull().all(1),'sum_hourly']=np.nan
frame_total.index=pd.date_range('2018-01-01', periods=13, freq='6H')
print(frame_total)
chem_1 chem_2 sum_hourly
2018-01-01 00:00:00 -5.0 6.0 1.0
2018-01-01 06:00:00 9.0 -1.0 8.0
2018-01-01 12:00:00 -1.0 -4.0 -5.0
2018-01-01 18:00:00 4.0 NaN 4.0
2018-01-02 00:00:00 -2.0 -7.0 -9.0
2018-01-02 06:00:00 3.0 -5.0 -2.0
2018-01-02 12:00:00 4.0 5.0 9.0
2018-01-02 18:00:00 NaN NaN NaN
2018-01-03 00:00:00 NaN 10.0 10.0
2018-01-03 06:00:00 NaN -9.0 -9.0
2018-01-03 12:00:00 8.0 8.0 16.0
2018-01-03 18:00:00 NaN 6.0 6.0
2018-01-04 00:00:00 9.0 NaN 9.0
ПРИМЕР: Ниже описаны простые groupby
и join
, которые заполнят столбец sum_24_a, в котором суммируются значения часовых сумм за календарный день. Однако недавно я обнаружил, что могу сократить это, применив вторую часть кода, которая заполняет столбец «sum_24_b»
# first part: create a dataframe and then join to get column 'sum_24_a'
frame_sum=frame_total.groupby(frame_total.index.date)['sum_hourly'].sum().to_frame('sum_24_a')
frame_total=frame_total.join(frame_sum)
# second part: directly create column 'sum_24_b' without the need of joining
frame_total['sum_24_b']=frame_total['sum_hourly'].groupby(frame_total.index.date).sum()
print(frame_total)
chem_1 chem_2 sum_hourly sum_24_a sum_24_b
2018-01-01 00:00:00 -5.0 6.0 1.0 8.0 8.0
2018-01-01 06:00:00 9.0 -1.0 8.0 NaN NaN
2018-01-01 12:00:00 -1.0 -4.0 -5.0 NaN NaN
2018-01-01 18:00:00 4.0 NaN 4.0 NaN NaN
2018-01-02 00:00:00 -2.0 -7.0 -9.0 -2.0 -2.0
2018-01-02 06:00:00 3.0 -5.0 -2.0 NaN NaN
2018-01-02 12:00:00 4.0 5.0 9.0 NaN NaN
2018-01-02 18:00:00 NaN NaN NaN NaN NaN
2018-01-03 00:00:00 NaN 10.0 10.0 23.0 23.0
2018-01-03 06:00:00 NaN -9.0 -9.0 NaN NaN
2018-01-03 12:00:00 8.0 8.0 16.0 NaN NaN
2018-01-03 18:00:00 NaN 6.0 6.0 NaN NaN
2018-01-04 00:00:00 9.0 NaN 9.0 9.0 9.0
ВОПРОС: Есть ли подобное предложение для выполнения после более сложных GROUPBY, AGG и JOIN без необходимости создавать фрейм данных frame_day и затем присоединять его к оригиналу, как показано ниже?
frame_day=frame_total.between_time('10:00:00', '16:00:00').\
groupby(frame_total.between_time('10:00:00', '16:00:00').index.date)['sum_hourly'].\
agg([('sum_day', lambda x: x.sum()), \
('positive_sum_day', lambda x: x[x>0].sum()), \
('negative_sum_day', lambda x: x[x<0].sum())])
frame_total=frame_total.join(frame_day)
print(frame_total.head(8))
chem_1 chem_2 sum_hourly sum_24_a sum_24_b \
2018-01-01 00:00:00 -5.0 6.0 1.0 8.0 8.0
2018-01-01 06:00:00 9.0 -1.0 8.0 NaN NaN
2018-01-01 12:00:00 -1.0 -4.0 -5.0 NaN NaN
2018-01-01 18:00:00 4.0 NaN 4.0 NaN NaN
2018-01-02 00:00:00 -2.0 -7.0 -9.0 -2.0 -2.0
2018-01-02 06:00:00 3.0 -5.0 -2.0 NaN NaN
2018-01-02 12:00:00 4.0 5.0 9.0 NaN NaN
2018-01-02 18:00:00 NaN NaN NaN NaN NaN
sum_day positive_sum_day negative_sum_day
2018-01-01 00:00:00 -5.0 0.0 -5.0
2018-01-01 06:00:00 NaN NaN NaN
2018-01-01 12:00:00 NaN NaN NaN
2018-01-01 18:00:00 NaN NaN NaN
2018-01-02 00:00:00 9.0 9.0 0.0
2018-01-02 06:00:00 NaN NaN NaN
2018-01-02 12:00:00 NaN NaN NaN
2018-01-02 18:00:00 NaN NaN NaN
Надеюсь, мой вопрос и пример понятны. Заранее спасибо!