Appliquer la fonction Python à une colonne pandas et appliquer la sortie à plusieurs colonnes
Bonjour la communauté,
J'ai lu tellement de réponses et de blogs que je ne suis pas en mesure de comprendre quelle chose simple me manque !. J'utilise la fonction «conditions» pour définir toutes les conditions et l'appliquer à une colonne de dataframe. Et si la condition est satisfaite, il devrait créer / mettre à jour 2 nouvelles colonnes de dataframe 'cat' et 'subcat'.
Ce serait d'une grande aide si vous pouviez m'aider ici!
dict = {'remark':['NA','NA','Category1','Category2','Category3'],
'desc':['Present','Present','NA','Present','NA']
}
df = pd.DataFrame(dict)
Dataframe ressemble à ceci:
remark desc
0 NA Present
1 NA Present
2 Category1 NA
3 Category2 Present
4 Category3 NA
J'ai écrit une fonction pour définir les conditions comme ci-dessous:
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)
J'ai plusieurs idées pour exécuter la fonction ci-dessus sur la colonne dataframe mais pas de chance.
df[['cat','subcat']] = df['remark'].apply(lambda x: pd.Series([conditions(df)[0],conditions(df)[1]]))
Mon dataframe attendu devrait ressembler à ceci:
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
Merci beaucoup.
Réponses
Une façon de contourner ce problème consiste à comprendre une liste:
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
La réponse de @ dm2 montre comment y parvenir avec votre fonction. Le premier apply(conditions)
crée une série contenant des tuples, le second apply
crée des colonnes individuelles, formant une trame de données que vous pouvez ensuite affecter à cat
et subcat
.
La raison pour laquelle je suggère une compréhension de liste est que, lorsque vous avez affaire à des chaînes, et dans Pandas, travailler avec des chaînes via python vanilla est le plus souvent plus rapide. De plus, avec la compréhension de la liste, le traitement est effectué une fois, vous n'avez pas besoin d'appliquer la fonction de conditions, puis d'appeler pd.Series
. Cela vous donne une vitesse plus rapide. Les tests affirmeront ou démystifieront cela.
Vous pourriez faire:
df[['cat','subcat']] = df['remark'].apply(conditions).apply(pd.Series)
Production:
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
Edit: C'est peut-être le moyen le plus simple d'appliquer votre fonction que vous avez déjà, mais au cas où vous auriez un énorme DataFrame, pour un code plus rapide, consultez la réponse de @sammywemmy en utilisant la compréhension de liste.
Vous dataframe
passez le tout là où il vous suffit de passer la variable lambda ( x
).
df[['cat','subcat']] = df['remark'].apply(lambda x: pd.Series([*conditions(x)]))
*
sur les iterables peuvent unpack
les faire ainsi vous n'avez pas besoin d'appeler la même fonction deux fois pour extraire la sortie. Peut-être que le compilateur résout cela mais je ne pense pas ...
Vous pouvez utiliser series.replace
avec un dictionnaire de mappage
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