Использование словаря для добавления некоторых столбцов в фрейм данных с функцией назначить - PullRequest
1 голос
/ 04 октября 2019

Я использовал python и pandas для статистического анализа данных, и в какой-то момент мне нужно было добавить несколько новых столбцов с функцией назначения

df_res = (
    df
    .assign(col1 = lambda x: np.where(x['event'].str.contains('regex1'),1,0))
    .assign(col2 = lambda x: np.where(x['event'].str.contains('regex2'),1,0))
    .assign(mycol = lambda x: np.where(x['event'].str.contains('regex3'),1,0))
    .assign(newcol = lambda x: np.where(x['event'].str.contains('regex4'),1,0))
)

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

Dic = {'col1':'regex1','col2':'regex2','mycol':'regex3','newcol':'regex4'}

df_res = (
    df
    .assign(...using Dic here...)
)

Мне нужно добавить больше столбцов позже, и я думаю, что это облегчит добавление новыхстолбцы позже.

Ответы [ 3 ]

1 голос
/ 05 октября 2019

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.assign.html

Возможно присвоение нескольких столбцов в рамках одного назначения. Для Python 3.6 и выше более поздние элементы в «** kwargs» могут ссылаться на вновь созданные или измененные столбцы в «df»;элементы вычисляются и присваиваются в 'df' по порядку. Для Python 3.5 и ниже порядок аргументов ключевых слов не указан, вы не можете ссылаться на вновь созданные или измененные столбцы. Все элементы вычисляются сначала, а затем присваиваются в алфавитном порядке. Изменено в версии 0.23.0: порядок аргументов ключевого слова поддерживается для Python 3.6 и более поздних версий.

Если вы отобразите все свои регулярные выражения так, чтобы каждое значение словаря содержало лямбда, а не просто регулярное выражение, вы можете простораспакуйте файл dic в assign:

lambda_dict = {
    col:
    lambda x, regex=regex: (
        x['event'].
        str.contains(regex)
        .astype(int)
    ) 
    for col, regex in Dic.items()
}
res = df.assign(**lambda_dict)

EDIT Вот пример:

import pandas as pd
import random

random.seed(0)
events = ['apple_one', 'chicken_one', 'chicken_two', 'apple_two']
data = [random.choice(events) for __ in range(10)]
df = pd.DataFrame(data, columns=['event'])

regex_dict = {
        'apples': 'apple',
        'chickens': 'chicken',
        'ones': 'one',
        'twos': 'two',
}

lambda_dict = {
    col:
    lambda x, regex=regex: (
        x['event']
        .str.contains(regex)
        .astype(int)
    )
    for col, regex in regex_dict.items()
}

res = df.assign(**lambda_dict)
print(res)

# Output
         event  apples  chickens  ones  twos
0    apple_two       1         0     0     1
1    apple_two       1         0     0     1
2    apple_one       1         0     1     0
3  chicken_two       0         1     0     1
4    apple_two       1         0     0     1
5    apple_two       1         0     0     1
6  chicken_two       0         1     0     1
7    apple_two       1         0     0     1
8  chicken_two       0         1     0     1
9  chicken_one       0         1     1     0

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

0 голосов
/ 04 октября 2019

Это может делать то, что вы хотите сделать

pd.concat([df,pd.DataFrame({a:list(df["event"].str.contains(b)) for a,b in Dic.items()})],axis=1)

На самом деле использование цикла for сделает то же самое

0 голосов
/ 04 октября 2019

Если я правильно понимаю ваш вопрос, вы пытаетесь переименовать столбцы, и в этом случае я думаю, что вы можете просто использовать Pandas функцию переименования . Это будет выглядеть как

df_res = df_res.rename(mapper=Dic)

-Ben

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...