Условные обозначения и методы, отличные от итерации для фреймов данных python 3 pandas

#python-3.x #pandas #dataframe #pandas-groupby #python-datetime

#python-3.x #pandas #фрейм данных #pandas-groupby #python-datetime

Вопрос:

Я продолжаю работать над своими навыками pandas и столкнулся с некоторыми сложными проблемами. Эта проблема связана с двумя фреймами данных df1 и df2. df1 содержит время события и соответствующие сведения о каждом событии. df2 содержит период времени, установленный временем начала и временем остановки.

ЦЕЛЬ:

  1. сгруппируйте все события по периоду времени.
  2. проверьте, увеличивается ли количество в течение периода времени и все ли коды одинаковы для периода времени
  3. создайте новый столбец в 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 Счастливого кодирования!