Возвращает количество вхождений на основе hour — Pandas

#python #pandas #datetime #group-by

#python #pandas #дата и время #группировать по

Вопрос:

Я пытаюсь вернуть максимальное значение, сгруппированное по часам. Я пытался добиться этого, используя следующее, но существует несколько одинаковых часов (групп). Я надеюсь вернуть максимальное значение только для каждого часа.

 d = ({
    'Time' : ['0/1/1900 8:00:00','0/1/1900 9:59:00','0/1/1900 10:00:00','0/1/1900 12:29:00','0/1/1900 12:30:00','0/1/1900 13:00:00','0/1/1900 13:02:00','0/1/1900 13:15:00','0/1/1900 13:20:00','0/1/1900 18:10:00','0/1/1900 18:15:00','0/1/1900 18:20:00','0/1/1900 18:25:00','0/1/1900 18:45:00','0/1/1900 18:50:00','0/1/1900 19:05:00','0/1/1900 19:07:00','0/1/1900 21:57:00','0/1/1900 22:00:00','0/1/1900 22:30:00','0/1/1900 22:35:00','1/1/1900 3:00:00','1/1/1900 3:05:00','1/1/1900 3:20:00','1/1/1900 3:25:00'],                 
    'People' : [1,1,2,2,3,3,2,2,3,3,4,4,3,3,2,2,3,3,4,4,3,3,2,2,1],                      
     })

df = pd.DataFrame(data = d)

df['Time'] = ['/'.join([str(int(x.split('/')[0]) 1)]   x.split('/')[1:]) for x in df['Time']]
df['Time'] = pd.to_datetime(df['Time'], format='%d/%m/%Y %H:%M:%S') 

df = df.groupby([pd.Grouper(key='Time',freq='H'),df.People]).size().reset_index(name='count')

print(df)

                  Time  People  count
0  1900-01-01 08:00:00       1      1
1  1900-01-01 09:00:00       1      1
2  1900-01-01 10:00:00       2      1
3  1900-01-01 12:00:00       2      1
4  1900-01-01 12:00:00       3      1
5  1900-01-01 13:00:00       2      2
6  1900-01-01 13:00:00       3      2
7  1900-01-01 18:00:00       2      1
8  1900-01-01 18:00:00       3      3
9  1900-01-01 18:00:00       4      2
10 1900-01-01 19:00:00       2      1
11 1900-01-01 19:00:00       3      1
12 1900-01-01 21:00:00       3      1
13 1900-01-01 22:00:00       3      1
14 1900-01-01 22:00:00       4      2
15 1900-01-02 03:00:00       1      1
16 1900-01-02 03:00:00       2      2
17 1900-01-02 03:00:00       3      1
  

Ожидаемый результат:

               Time  People  count
0  1900-01-01 08:00:00       1      1
1  1900-01-01 09:00:00       1      1
2  1900-01-01 10:00:00       2      2
3  1900-01-01 12:00:00       2      3
4  1900-01-01 13:00:00       2      3
5  1900-01-01 18:00:00       2      4
6  1900-01-01 19:00:00       2      3
7  1900-01-01 21:00:00       3      3
8  1900-01-01 22:00:00       3      4
9  1900-01-02 03:00:00       1      3
  

Комментарии:

1. Каков ваш ожидаемый результат?

2. Каждый час каждой даты? или каждый час всех дат объединяется?

3. @Chris. Даты будут длиться более суток, но времена никогда не будут перекрываться, если это имеет смысл. Я смотрю на 20-часовой таймфрейм, который превышает полночь

4. @coldspeed, это было включено

5. Вместо этого вы ищете df.groupby(df.Time.dt.floor('H'))['People'].count() ?

Ответ №1:

Используйте pandas.DataFrame.groupby . Дано df :

                    Time  People
0   1900-01-01 08:00:00       1
1   1900-01-01 09:00:00       1
2   1900-01-01 10:00:00       2
3   1900-01-01 12:00:00       2
4   1900-01-01 12:00:00       3
5   1900-01-01 13:00:00       2
6   1900-01-01 13:00:00       3
7   1900-01-01 18:00:00       2
8   1900-01-01 18:00:00       3
9   1900-01-01 18:00:00       4
10  1900-01-01 19:00:00       2
11  1900-01-01 19:00:00       3
12  1900-01-01 21:00:00       3
13  1900-01-01 22:00:00       3
14  1900-01-01 22:00:00       4
15  1900-01-02 03:00:00       1
16  1900-01-02 03:00:00       2
17  1900-01-02 03:00:00       3
  

df.groupby('Time')['People'].max() ВОЗВРАТ:

 Time
1900-01-01 08:00:00    1
1900-01-01 09:00:00    1
1900-01-01 10:00:00    2
1900-01-01 12:00:00    3
1900-01-01 13:00:00    3
1900-01-01 18:00:00    4
1900-01-01 19:00:00    3
1900-01-01 21:00:00    3
1900-01-01 22:00:00    4
1900-01-02 03:00:00    3
  

Комментарии:

1. Спасибо @Chris. Возможно, это должен быть отдельный вопрос. Но насколько сложно разделить это еще больше. Как и при возврате максимального значения для каждого 15-минутного сегмента, а не для каждого часа.

Ответ №2:

Чтобы добиться большего контроля над самими элементами, вы могли бы выполнить итерацию по отдельным ключам df и получить значение max () для других столбцов, затем изменить их по своему усмотрению и позже воссоздать df. Это должно сработать:

 import pandas as pd

d = ({
    'Time' : ['0/1/1900 8:00:00','0/1/1900 9:59:00','0/1/1900 10:00:00','0/1/1900 12:29:00','0/1/1900 12:30:00','0/1/1900 13:00:00','0/1/1900 13:02:00','0/1/1900 13:15:00','0/1/1900 13:20:00','0/1/1900 18:10:00','0/1/1900 18:15:00','0/1/1900 18:20:00','0/1/1900 18:25:00','0/1/1900 18:45:00','0/1/1900 18:50:00','0/1/1900 19:05:00','0/1/1900 19:07:00','0/1/1900 21:57:00','0/1/1900 22:00:00','0/1/1900 22:30:00','0/1/1900 22:35:00','1/1/1900 3:00:00','1/1/1900 3:05:00','1/1/1900 3:20:00','1/1/1900 3:25:00'],
    'People' : [1,1,2,2,3,3,2,2,3,3,4,4,3,3,2,2,3,3,4,4,3,3,2,2,1],
     })

df = pd.DataFrame(data = d)

df['Time'] = ['/'.join([str(int(x.split('/')[0]) 1)]   x.split('/')[1:]) for x in df['Time']]
df['Time'] = pd.to_datetime(df['Time'], format='%d/%m/%Y %H:%M:%S')


df = df.groupby([pd.Grouper(key='Time',freq='H'),df.People]).size().reset_index(name='count')

single_times = set(df['Time'])
p, c = [ [] for i in range(2) ]
for v in single_times :
    c.append(max(df.loc[df['Time'] == v]['count']))
    p.append(max(df.loc[df['Time'] == v]['People']))

###make something with c/p

dfdata = {
    'Time' : list(single_times),
    'People' : p,
    'Count' : c
}
df2 = pd.DataFrame(data = dfdata)

print(df2)
  

Могли бы быть еще более быстрые подходы.