Примените функцию Python к одному столбцу pandas и примените вывод к нескольким столбцам
Привет, сообщество,
Я прочитал так много ответов и блогов, но не могу понять, какую простую вещь я упускаю! Я использую функцию «условия», чтобы определить все условия и применить их к одному столбцу фрейма данных. И если условие удовлетворяется, он должен создать / обновить 2 новых столбца фрейма данных «cat» и «subcat».
Было бы здорово, если бы вы, ребята, помогли мне здесь!
dict = {'remark':['NA','NA','Category1','Category2','Category3'],
'desc':['Present','Present','NA','Present','NA']
}
df = pd.DataFrame(dict)
Dataframe выглядит примерно так:
remark desc
0 NA Present
1 NA Present
2 Category1 NA
3 Category2 Present
4 Category3 NA
Я написал функцию для определения условий, как показано ниже:
def conditions(s):
if (s == 'Category1'):
x = 'insufficient'
y = 'resolution'
elif (s=='Category2):
x= 'insufficient'
y= 'information'
elif (s=='Category3):
x= 'Duplicate'
y= 'ID repeated'
else:
x= 'NA'
y= 'NA'
return (x,y)
У меня есть несколько идей для выполнения вышеуказанной функции в столбце фрейма данных, но не повезло.
df[['cat','subcat']] = df['remark'].apply(lambda x: pd.Series([conditions(df)[0],conditions(df)[1]]))
Мой ожидаемый фрейм данных должен выглядеть примерно так:
remark desc cat subcat
0 NA Present NA NA
1 NA Present NA NA
2 Category1 NA insufficient resolution
3 Category2 Present insufficient information
4 Category3 NA Duplicate ID repeated
Огромное спасибо.
Ответы
Один из способов обойти это - составить список:
df[['cat', 'subcat']] = [("insufficient", "resolution") if word == "Category1" else
("insufficient", "information") if word == "Category2" else
("Duplicate", "ID repeated") if word == "Category3" else
("NA", "NA")
for word in df.remark]
remark desc cat subcat
0 NA Present NA NA
1 NA Present NA NA
2 Category1 NA insufficient resolution
3 Category2 Present insufficient information
4 Category3 NA Duplicate ID repeated
Ответ @dm2 показывает, как это сделать с помощью вашей функции. Первый apply(conditions)
создает серию, содержащую кортежи, второй apply
создает отдельные столбцы, формируя фрейм данных, который затем можно назначить cat
и subcat
.
Причина, по которой я предлагаю понимание списка, заключается в том, что, когда вы имеете дело со строками, а в Pandas, работа со строками через ванильный питон чаще всего выполняется быстрее. Кроме того, с пониманием списка обработка выполняется один раз, вам не нужно применять функцию условий, а затем вызывать pd.Series
. Это дает вам более высокую скорость. Тестирование подтвердит или опровергнет это.
Вы могли сделать:
df[['cat','subcat']] = df['remark'].apply(conditions).apply(pd.Series)
Вывод:
remark desc cat subcat
0 NA Present NA NA
1 NA Present NA NA
2 Category1 NA insufficient resolution
3 Category2 Present insufficient information
4 Category3 NA Duplicate ID repeated
Изменить: это может быть более простой способ применить вашу функцию, которая у вас уже есть, но в случае, если у вас огромный DataFrame, для более быстрого кода проверьте ответ @sammywemmy, используя понимание списка.
Вы передаете все, dataframe
где вам просто нужно передать лямбда-переменную ( x
).
df[['cat','subcat']] = df['remark'].apply(lambda x: pd.Series([*conditions(x)]))
*
на итерациях могут unpack
они, поэтому вам не нужно дважды вызывать одну и ту же функцию для извлечения вывода. Возможно, компилятор разрешит это, но я так не думаю ...
Вы можете использовать series.replace
с картографическим словарем
df['cat'] = df.remark.replace({'Category1': 'insufficient',
'Category2': 'insufficient', 'Category3': 'Duplicate'})
df['subcat'] = df.remark.replace({'Category1': 'resolution',
'Category2': 'information', 'Category3': 'ID repeated'})
print(df)
remark desc cat subcat
0 NA Present NA NA
1 NA Present NA NA
2 Category1 NA insufficient resolution
3 Category2 Present insufficient information
4 Category3 NA Duplicate ID repeated