新数据框:按日期分组,按时间分组的条件,具有if条件的求和值

时间:2019-08-13 14:19:21

标签: python pandas dataframe pandas-groupby

我正试图为此找到一种“熊猫”解决方案:

我有一个包含两列的数据框,一列用于日期时间,一列用于数值。

对此数据框进行假设:

datarange=pd.date_range('01-05-2018 13:00:00', periods=12000, freq="1H")
range_series=pd.Series(np.random.randint(-2,2,size=12000).astype(float), index=datarange)
frame=pd.DataFrame(range_series, columns=['diffs'])
frame.index.name='datetime'

输出是这样的:

print(frame.head(10), frame.tail(10))

           datetime    diffs
2018-01-05 13:00:00   -2.0
2018-01-05 14:00:00    0.0
2018-01-05 15:00:00   -2.0
2018-01-05 16:00:00    1.0
2018-01-05 17:00:00    1.0
2018-01-05 18:00:00    1.0
2018-01-05 19:00:00   -1.0
2018-01-05 20:00:00   -2.0
2018-01-05 21:00:00   -2.0
2018-01-05 22:00:00   -2.0
Freq: H, dtype: float64
           datetime    diffs
2019-05-20 03:00:00   -1.0
2019-05-20 04:00:00   -1.0
2019-05-20 05:00:00    0.0
2019-05-20 06:00:00    1.0
2019-05-20 07:00:00    0.0
2019-05-20 08:00:00   -2.0
2019-05-20 09:00:00    1.0
2019-05-20 10:00:00   -1.0
2019-05-20 11:00:00    1.0
2019-05-20 12:00:00   -2.0
Freq: H, dtype: float64

我需要使用新列创建一个新的数据框:

新列A:如果diffs.value> 0

,则从5:00到21:00相同日期的差异总和。

新列B:如果diffs.value <0

,则从5:00到21:00相同日期的差异总和。

新列C:如果'y-m-d 22:00:00'组到'y-m-d + 1 4:00:00'的diffs.value> 0,则diffs的总和

新列D:如果对'y-m-d 22:00:00'到'y-m-d + 1 4:00:00'组的diffs.value <0,则求和的总和

因此,实际上有5个新列:

1)日期

2)容纳5到21小时之间每天的阳性差异总和

3)容纳从5小时到21小时每天的负差异总和

4)容纳从一天的22:00到第二天的4:00的正差异之和

5)容纳从一天的22:00到第二天的4:00的负差的总和

我可以开始遍历列表以创建新列表,然后将它们重新组合到新的数据框中。但是我试图找出是否可以以某种方式分组并在不同的列中应用条件并进行汇总。

注意:(4)和(5)中所述的金额应在第一天的日期之内。

我欢迎您的输入。我不是开发人员,而且绝对没有熊猫经验,但是我尝试探索的图书馆似乎提供了巨大的可能性。

希望我的描述很清楚,谢谢。

1 个答案:

答案 0 :(得分:0)

毕竟是我自己做的...我发布了代码,但欢迎使用更简洁,简短,更优雅的代码的人。

从此数据帧开始

dates=pd.date_range('01-05-2018 13:00:00', periods=12000, freq="1H")
range_series=pd.Series(np.random.randint(-2,2,size=12000).astype(float), index=dates)
df=pd.DataFrame(range_series, columns=['diffs'])
df.index.name='datetime'

我创建日期和时间列:

df['date']=df.index.date
df['time']=df.index.time

我将新列放在最前面(这样我就可以控制自己的计算):

new_df = df.iloc[:, np.r_[1,2,0]]

我创建两个不同的数据帧,将每次的时间切片:

day_df=new_df.between_time('05:00', '21:00')
night_df=new_df.between_time('22:00','04:00')

我按“日期”分组,并汇总了三种方法(总和,正数求和,负数求和):

day_change=day_df.groupby(day_df['date'])['diffs'].\
        agg([('daytime change' , lambda x : x.sum()) ,\
             ('daytime negative change' , lambda x : x[x < 0].sum()) , \
             ('daytime positive change' , lambda x : x[x > 0].sum())])
night_change=night_df.groupby(night_df['date'])['diffs'].\
        agg([('nighttime change' , lambda x : x.sum()) ,\
             ('nighttime negative change' , lambda x : x[x < 0].sum()) , \
             ('nighttime positive change' , lambda x : x[x > 0].sum())])

在两个数据帧的行数不相等的情况下,我通过水平轴将两个数据帧连接为“内部联接”:

change=pd.concat([day_change,night_change], axis=1, join='inner')

然后我得到所需的输出:

print(change.head(1))
            daytime change  daytime negative change  daytime positive change  \
date                                                                           
2018-01-05            -7.0                    -10.0                      3.0   

            nighttime change  nighttime negative change  \
date                                                      
2018-01-05               0.0                        0.0   

            nighttime positive change  
date                                   
2018-01-05                        0.0