#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)
Могли бы быть еще более быстрые подходы.