#python-3.x #pandas #dataframe #pandas-groupby #python-datetime
#python-3.x #pandas #фрейм данных #pandas-groupby #python-datetime
Вопрос:
Я продолжаю работать над своими навыками pandas и столкнулся с некоторыми сложными проблемами. Эта проблема связана с двумя фреймами данных df1 и df2. df1 содержит время события и соответствующие сведения о каждом событии. df2 содержит период времени, установленный временем начала и временем остановки.
ЦЕЛЬ:
- сгруппируйте все события по периоду времени.
- проверьте, увеличивается ли количество в течение периода времени и все ли коды одинаковы для периода времени
- создайте новый столбец в df2 и верните True этому столбцу, если ОБА фрагмента из части 2 имеют значение True, и False, если это не так или в течение периода нет событий.
код:
import pandas as pd
df1 = {'Event': ['2020-12-01 00:10:22', '2020-12-01 00:15:11','2020-12-01 00:18:00',
'2020-12-01 00:31:00', '2020-12-01 00:54:00' , '2020-12-01 01:01:00' ,
'2020-12-01 01:19:00' , '2020-12-01 01:23:00' , '2020-12-01 01:24:00' ,
'2020-12-01 01:56:00' , '2020-12-01 21:02:00', '2020-12-01 02:41:00',
'2020-12-01 02:44:00' , '2020-12-01 03:19:00' ,'2020-12-01 03:22:00' ,
'2020-12-01 03:49:00' , '2020-12-01 05:24:00' ,'2020-12-01 05:56:00' ,
'2020-12-01 08:02:00'
] ,
'Count' : [1 , 2 , 4 , 2 , 5 ,
3 , 7 , 9 , 10 , 1 ,
2 , 5 , 6 , 10 , 5 ,
6 ,7 , 8 , 3] ,
'Code' : ['A' , 'A' , 'A' , 'A' , 'B' ,
'B' , 'B' , 'B' , 'B' , 'B' ,
'C' , 'C' , 'C' , 'C' , 'C' ,
'D' , 'D' , 'D' , 'D']
}
df1 = pd.DataFrame(df1 , columns = ['Event' , 'Count' , 'Code'])
df1['Event'] = pd.to_datetime(df1['Event'])
df
Event Count Code
0 2020-12-01 00:10:22 1 A
1 2020-12-01 00:15:11 2 A
2 2020-12-01 00:18:00 4 A
3 2020-12-01 00:31:00 2 A
4 2020-12-01 00:54:00 5 B
5 2020-12-01 01:01:00 3 B
6 2020-12-01 01:19:00 7 B
7 2020-12-01 01:23:00 9 B
8 2020-12-01 01:24:00 10 B
9 2020-12-01 01:56:00 1 B
10 2020-12-01 21:02:00 2 C
11 2020-12-01 02:41:00 5 C
12 2020-12-01 02:44:00 6 C
13 2020-12-01 03:19:00 10 C
14 2020-12-01 03:22:00 5 C
15 2020-12-01 03:49:00 6 D
16 2020-12-01 05:24:00 7 D
17 2020-12-01 05:56:00 8 D
18 2020-12-01 08:02:00 3 D
создание кода df2 :
df2 = {'Start Time' : ['2020-12-01 00:00:00', '2020-12-01 00:30:00','2020-12-01 01:30:00',
'2020-12-01 02:30:00', '2020-12-01 03:30:00' , '2020-12-01 04:30:00' ,
'2020-12-01 05:30:00' , '2020-12-01 07:30:00' , '2020-12-01 10:30:00' ,
'2020-12-01 15:00:00' , '2020-12-02 21:00:00'] ,
'End Time' : ['2020-12-01 00:30:00', '2020-12-01 01:30:00','2020-12-01 02:30:00',
'2020-12-01 03:30:00', '2020-12-01 04:30:00' , '2020-12-01 05:30:00' ,
'2020-12-01 07:30:00' , '2020-12-01 10:30:00' , '2020-12-01 15:00:00' ,
'2020-12-01 21:00:00' , '2020-12-02 00:00:00']
}
df2 = pd.DataFrame(df2 , columns = ['Start Time' , 'End Time'])
df2['Start Time'] = pd.to_datetime(df2['Start Time'])
df2['End Time'] = pd.to_datetime(df2['End Time'])
df2
Start Time End Time
0 2020-12-01 00:00:00 2020-12-01 00:30:00
1 2020-12-01 00:30:00 2020-12-01 01:30:00
2 2020-12-01 01:30:00 2020-12-01 02:30:00
3 2020-12-01 02:30:00 2020-12-01 03:30:00
4 2020-12-01 03:30:00 2020-12-01 04:30:00
5 2020-12-01 04:30:00 2020-12-01 05:30:00
6 2020-12-01 05:30:00 2020-12-01 07:30:00
7 2020-12-01 07:30:00 2020-12-01 10:30:00
8 2020-12-01 10:30:00 2020-12-01 15:00:00
9 2020-12-01 15:00:00 2020-12-01 21:00:00
10 2020-12-01 21:00:00 2020-12-02 00:00:00
СТРАТЕГИИ:
Моя стратегия заключается в использовании pd.Dataframe.between_time, а затем лямбда-функции для проверки условного оператора, но, похоже, я не могу заставить его работать.
Ниже приведен желаемый результат:
Start Time End Time Test
0 2020-12-01 00:00:00 2020-12-01 00:30:00 True
1 2020-12-01 00:30:00 2020-12-01 01:30:00 False
2 2020-12-01 01:30:00 2020-12-01 02:30:00 True
3 2020-12-01 02:30:00 2020-12-01 03:30:00 False
4 2020-12-01 03:30:00 2020-12-01 04:30:00 True
5 2020-12-01 04:30:00 2020-12-01 05:30:00 True
6 2020-12-01 05:30:00 2020-12-01 07:30:00 True
7 2020-12-01 07:30:00 2020-12-01 10:30:00 True
8 2020-12-01 10:30:00 2020-12-01 15:00:00 False
9 2020-12-01 15:00:00 2020-12-01 21:00:00 False
10 2020-12-02 21:00:00 2020-12-02 00:00:00 False
Комментарии:
1. «Похоже, это не работает», не могли бы вы поделиться кодом, который вы пробовали до сих пор, и в чем проблема с этим кодом.
2. Я пробовал несколько разных вещей, но общая стратегия заключается в использовании between_time, а затем either .apply в этой общей структуре: df[‘новое имя столбца’] = df[‘имя столбца’].apply(лямбда x: ‘значение, если условие выполнено’, если условие x еще ‘значение, если условие не выполнено»), но, похоже, это работает только для одного условия.
3. @kdbaseball8 Я предполагаю, что вывод для строки с индексом
2
должен бытьTrue
, а для индекса10
он должен бытьFalse
4. нет, это событие просто не в порядке, но должно быть применено к правильному временному интервалу
5. извините, вы правы, я изменю это, это была ошибка ввода
Ответ №1:
Вы можете использовать пользовательскую функцию, которая выдает логическое значение на основе заданных условий. Здесь мы использовали Series.is_monotonic_increasing
для проверки Count
увеличения и Series.nunique
проверки того, все ли коды одинаковы для данного периода времени:
def f():
for x, y in df2.to_numpy():
s = df1[df1['Event'].between(x, y)]
yield s['Count'].is_monotonic_increasing amp; s['Code'].nunique() == 1
df2['Test'] = list(f())
Результат:
Start Time End Time Test
0 2020-12-01 00:00:00 2020-12-01 00:30:00 True
1 2020-12-01 00:30:00 2020-12-01 01:30:00 False
2 2020-12-01 01:30:00 2020-12-01 02:30:00 True
3 2020-12-01 02:30:00 2020-12-01 03:30:00 False
4 2020-12-01 03:30:00 2020-12-01 04:30:00 True
5 2020-12-01 04:30:00 2020-12-01 05:30:00 True
6 2020-12-01 05:30:00 2020-12-01 07:30:00 True
7 2020-12-01 07:30:00 2020-12-01 10:30:00 True
8 2020-12-01 10:30:00 2020-12-01 15:00:00 False
9 2020-12-01 15:00:00 2020-12-01 21:00:00 False
10 2020-12-02 21:00:00 2020-12-02 00:00:00 False
Комментарии:
1. Спасибо, Шубхам! Это работает и полностью отличается от того, как я думал, что должен решить проблему.
2. @kdbaseball8 Счастливого кодирования!