March 7, 2022

Манипуляции со списковыми значениями в Pandas

Рассмотрим, как извлекать списочные значения из строк и проводить с ними некоторые операции средствами Pandas. Для примера воспользуемся таблицей следующего вида (инфа о вымышленных категориях магазинов в торговых центрах):

import pandas as pd

df = pd.DataFrame([[1, 'бытовая химия|одежда|кино|зоотовары'], [2, 'рестораны|автотовары|зоотовары'],
            [3, 'одежда|дети|кино'], [4, 'бытовая химия| дети|кино'], [5, None] ], columns=['id', 'categories'])
df

Разбиение строк на список категорий

Осуществляется с помощью векторизованного метода split, который принимает на вход разделитель:

df['categories'].str.split('|')

Формирование колонок с индикаторами присутствия категории

Для этого воспользуйтесь векторизованным методом get_dummies:

cats_df = df['categories'].str.get_dummies('|')
cats_df 

Создание обобщенной категории

Здесь не потребуется ничего нового. Сформируем новую категорию 'prefer_cat', включающую торговые центры, где есть одновременно и магазин 'бытовой химии' и 'кино':

df.loc[(cats_df['бытовая химия']==1)&(cats_df['кино']==1), 'prefer_cat'] = 1
df['prefer_cat'].fillna(0, inplace=True)
df

Такую же манипуляцию можно провести с использованием split. Нужные категории детектируются так:

sel1 = df['categories'].str.split('|').map(lambda x: ('бытовая химия' in x) and ('кино' in x) if x else False)
df[sel1]

или вовсе без векторизованных операций со строками:

def is_w_in_list(tab, w):
    l = [it for it in tab.split('|') if it==w]
    if len(l)>0:
        return 1
    else:
        return 0
sel2 = df['categories'].map(lambda x: is_w_in_list(x, 'бытовая химия') if x else False) & \
                                        df['categories'].map(lambda x: is_w_in_list(x, 'кино') if x else False)
df[sel2]