不同日子的熊猫群体活动

时间:2018-03-24 11:19:48

标签: python pandas dataframe

import pandas as pd

df = pd.DataFrame(data=[[1,1,10],[1,2,50],[1,3,20],[1,4,24],
[2,1,20],[2,2,10],[2,3,20],[2,4,34],[3,1,10],[3,2,50],
[3,3,20],[3,4,24],[3,5,24],[4,1,24]],columns=['day','hour','event'])

df
Out[4]: 
    day  hour  event
0     1     1     10
1     1     2     50
2     1     3     20 <- yes
3     1     4     24 <- yes
4     2     1     20 <- yes
5     2     2     10
6     2     3     20 <- yes
7     2     4     34 <- yes
8     3     1     10 <- yes
9     3     2     50
10    3     3     20 <- yes
11    3     4     24 <- yes
11    3     5     24 <- yes (here we have also an hour more)
12    4     1     24 <- yes 

现在我想总结第二天的小时= 3到小时= 1的事件数量。

预期结果应为

0 64
1 64
2 92

3 个答案:

答案 0 :(得分:1)

#convert columns to datetimes, for same day of next day subtract 2 hours:
a = pd.to_datetime(df['day'].astype(str) + ':' + df['hour'].astype(str), format='%d:%H')- pd.Timedelta(2, unit='h')
#get hours between 1 and 23 only ->in real 3,4...23,1
hours = a.dt.hour.between(1,23)
#create consecutives groups by filtering
df['a'] = hours.ne(hours.shift()).cumsum()
#filter only expected hours
df = df[hours]
#aggregate
df = df.groupby('a')['event'].sum().reset_index(drop=True)
print (df)
0    10
1    64
2    64
3    92
Name: event, dtype: int64

另一个类似的解决方案:

#create datetimeindex
df.index = pd.to_datetime(df['day'].astype(str)+':'+df['hour'].astype(str), format='%d:%H')
#shift by 2 hours 
df = df.shift(-2, freq='h')
#filter hours and first unnecessary event
df = df[(df.index.hour != 0) & (df.index.year != 1899)]
#aggregate
df = df.groupby(df.index.day)['event'].sum().reset_index(drop=True)
print (df)
0    64
1    64
2    92
Name: event, dtype: int64

另一种解决方案:

#filter out first values less as 3 and hours == 2
df = df[(df['hour'].eq(3).cumsum() > 0) & (df['hour'] != 2)]
#subtract 1 day by condition and aggregate
df = df['event'].groupby(np.where(df['hour'] < 3, df['day'] - 1, df['day'])).sum()
print (df)
1    64
2    64
3    92
Name: event, dtype: int64

答案 1 :(得分:0)

一种选择是删除hour2的所有条目,然后将结果合并为3个组并对其进行求和;

v = df[df.hour != 2][1:].event
np.add.reduceat(v, range(0, len(v), 3))

答案 2 :(得分:0)

一种方法是通过pd.DataFrame.apply使用自定义函数定义分组列。

然后groupby这个新专栏。

df['grouping'] = df.apply(lambda x: x['day']-2 if x['hour'] < 3 else x['day']-1, axis=1)

res = df.loc[(df['hour'] != 2) & (df['grouping'] >= 0)]\
        .groupby('grouping')['event'].sum()\
        .reset_index(drop=True)

<强>结果

0    64
1    64
2    92
Name: event, dtype: int64