Pandas / Python создает столбцы на основе нескольких условий со словарем

#python #pandas #dictionary #multiple-columns

#питон #панды #словарь #многоколоночный

Вопрос:

Я ищу более короткий и элегантный способ написания условия ниже, допустим, у меня есть 30 различных комбинаций. Можно ли сопоставить какой-то словарь с несколькими условиями или что-то еще?

 def set_name(df):
    if df['PRODUCT'] == 'A' and df['TYPE'] == 'C2':
        return 'AAC2'
    elif df['PRODUCT'] == 'A' and df['TYPE'] == 'C3':
        return 'AAC3'
    elif df['PRODUCT'] == 'B' and df['TYPE'] == 'C2':
        return 'BBC"'
    
df['RETURN'] = df.apply(set_name, axis=1)
 

Другой способ — приведенный ниже, который все еще довольно длинный, если у меня много комбинаций.

 conditions = [
    (df['PRODUCT'] == 'A') amp; (df['TYPE'] == 'C2'),
    (df['PRODUCT'] == 'A') amp; (df['TYPE'] == 'C3')
]

values = ['AAC2', 'AAC3']

df['RETURN'] = np.select(conditions, values)
 

Ответ №1:

Создайте вспомогательный фрейм данных и используйте левое соединение с помощью DataFrame.merge :

 products = ['A','A']
types = ['C2','C3']
values = ['AAC2', 'AAC3']

df1 = pd.DataFrame({'PRODUCT':products,
                    'TYPE':types,
                    'RETURN': values})


df = df.merge(df1, on=['PRODUCT','TYPE'], how='left')
 

Ответ №2:

Вы можете использовать двухуровневый словарь или словарь с кортежами (product, type) в качестве ключа:

Двухуровневый словарь …

 mapping = {
            'A': {'C2':'AAC2', 'C3':'AAC3'},
            'B': {'C2':'BBC'}
          } 
            
def set_name(df):
    product, ptype = df['PRODUCT'], df['TYPE']
    if product in mapping and ptype in mapping[product]:
        return mapping[product][ptype]
    else:
        # handle no-mapping situations
                                   

    
df['RETURN'] = df.apply(set_name, axis=1)
 

Или, используя ключи кортежа…

 mapping = {
            ('A','C2'): 'AAC2',
            ('A','C3'): 'AAC3',
            ('B','C2'): 'BBC'
          } 
            
def set_name(df):
    product, ptype = df['PRODUCT'], df['TYPE']
    if (product,ptype) in mapping:
        return mapping[product,ptype]
    else:
        # handle no-mapping situations
                                
    
df['RETURN'] = df.apply(set_name, axis=1)