Pandas: как фильтровать информацию о столбцах в Dataframe и обрабатывать ее по-разному

#python #pandas #feature-engineering

#python #pandas #разработка функций

Вопрос:

У меня есть фрейм данных, представляющий расписание некоторых ресторанов на неделю.

  • Что я хочу сделать, так это добавить столбец is_OpenSaturday в мой исходный df фрейм данных, который представляет, открыт ли ресторан по субботам (логическое значение: 0 или 1)

примечание: значение 0 or 0:0-0:0 просто означает, что ресторан закрыт в этот день.

 data = {
        'restaurant_id':  ['1', '2','3'],
        'Monday':  ['11:0-20:0', '11:30-22:0','11:30-21:0'],
        'Tuesday':  ['11:0-20:0', '11:30-22:0','11:30-22:0'],
        'Wednesday':  ['11:0-20:0', '11:30-22:0','11:30-21:0'],
        'Thursday':  ['11:0-20:0', '11:30-22:0','11:30-21:0'],
        'Friday':  ['11:0-22:0', '11:30-22:0','11:30-21:0'],
        'Saturday':  ['11:0-22:0', '0:0-0:0',0],
        'Sunday':  ['11:0-17:0', '16:30-21:30','11:30-21:0',],

        }

df = pd.DataFrame (data, columns = ['restaurant_id','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday',])

  

Какой может быть простой синтаксис для достижения этой цели?

Ответ №1:

(Один из) (синтаксически) простейший способ — применить lambda функцию к элементам Saturday столбца:

 df["is_OpenSaturday"] = df["Saturday"].apply(lambda el: 0 if el in ('0:0-0:0', '0') else 1)
  

Вывод:

 df["is_OpenSaturday"]
Out[5]: 
0    1
1    0
2    0
Name: is_OpenSaturday, dtype: int64
  

Лямбда-функция сообщает, что если ее строковое значение равно ‘0: 0-0: 0’ или ‘0’, то ресторан закрыт (возвращает 0). В противном случае он открыт (возвращает 1).

Обратите внимание, что нужно использовать df["is_OpenSaturday"] = , но не df.is_OpenSaturday = с левой стороны. is_OpenSaturday Столбец будет создан автоматически только с помощью [] оператора.

Также обратите внимание, что с точки зрения эффективности .apply() это последний вариант, который вы хотели бы попробовать. list(map()) Конструкция в целом лучше, если у вас много данных. Эквивалентный синтаксис показан следующим образом.

 df["is_OpenSaturday"] = list(map(lambda el: 0 if el in ('0:0-0:0', '0') else 1, df["Saturday"]))
  

Ответ №2:

Используйте регулярное выражение для проверки 0:0-0:0 или любую строку, начинающуюся с zero

 df['is_OpenSaturday']=np.where(df.Saturday.str.contains('0:0-0:0|^0'),0,1)

    restaurant_id      Monday     Tuesday   Wednesday    Thursday      Friday  
0             1   11:0-20:0   11:0-20:0   11:0-20:0   11:0-20:0   11:0-22:0   
1             2  11:30-22:0  11:30-22:0  11:30-22:0  11:30-22:0  11:30-22:0   
2             3  11:30-21:0  11:30-22:0  11:30-21:0  11:30-21:0  11:30-21:0   

    Saturday       Sunday  is_OpenSaturday  
0  11:0-22:0    11:0-17:0                1  
1    0:0-0:0  16:30-21:30                0  
2          0   11:30-21:0                0  
  

Ответ №3:

Используйте str.findall

 df.Saturday.str.findall(r'[^0:-]').astype(bool).astype(int)

Out[267]:
0    1
1    0
2    0
Name: Saturday, dtype: int32
  

Или

 df.Saturday.str.findall(r'[1-9]').astype(bool).astype(int)

Out[276]:
0    1
1    0
2    0
Name: Saturday, dtype: int32