Je souhaite ajouter une balise de texte à une nouvelle colonne dans une trame de données Pandas. L'exemple suivant fonctionne mais j'obtiens l'avertissement de copie et je ne comprends pas très bien si je dois l'ignorer dans ce cas.
Le DataFrame a simplement un caractère ou est une chaîne vide:
In [1]: import pandas as pd
In [2]: df=pd.DataFrame({('A'):['x','','x',''], ('B'):['x','x','','']})
In [3]: df
Out[3]:
A B
0 x x
1 x
2 x
3
Créez une nouvelle colonne appelée «msg»
In [4]: df['msg'] = ''
In [5]: df
Out[5]:
A B msg
0 x x
1 x
2 x
3
Définissez la colonne 'msg' sur 'rouge' si 'A' n'est pas une chaîne vide
In [6]: df['msg'][df['A'] != ''] = 'red;'
In [7]: df
Out[7]:
A B msg
0 x x red;
1 x
2 x red;
3
Concaténer «bleu» en fonction des valeurs de la colonne «B»
In [8]: df['msg'][df['B'] != ''] += 'blue;'
In [9]: df
Out[9]:
A B msg
0 x x red;blue;
1 x blue;
2 x red;
3
Alternativement, j'ai trouvé que l'utilisation de numpy.where a produit le résultat souhaité. Quelle est la bonne façon de procéder dans Pandas?
import numpy as np
df['msg'] += np.where(df['A'] != '','green;', '')
Mise à jour: 15/04/2018
Après mûre réflexion, il serait utile de conserver les données du DataFrame d'origine dans certains cas, tout en attachant une étiquette («couleur» dans cet exemple). La réponse de @COLDSPEED m'a conduit à ce qui suit (changer 'bleu;' en 'bleu:' et conserver les données de la colonne 'B' à inclure dans la balise dans ce cas):
df['msg'] = (v.where(df.applymap(len) > 0, '') +
df.where(df[['B']].applymap(len)>0,'')).agg(''.join, axis=1)
A B msg
0 x x red;blue:x
1 x blue:x
2 x red;
3
3 réponses
Si vous connaissez vos couleurs à l'avance, vous pouvez utiliser le masquage avec DataFrame.where
et str.join
pour y parvenir.
v = pd.DataFrame(
np.repeat([['red;', 'blue;']], len(df), axis=0),
columns=df.columns,
index=df.index
)
df['msg'] = v.where(df.applymap(len) > 0, '').agg(''.join, axis=1)
df
A B msg
0 x x red;blue;
1 x blue;
2 x red;
3
Utilisation de pandas.DataFrame.dot
Remarque spéciale que j'ai défini le dtype du tableau sur object
. Sinon, le dot
ne fonctionnera pas.
a = np.array(['red', 'blue;'], object)
df.assign(msg=df.astype(bool).dot(a))
A B msg
0 x x red;blue;
1 x blue;
2 x red;
3
Vous pouvez utiliser dot
et replace
(df!='').dot(df.columns).replace({'A':'red;','B':'blue;'},regex=True)
Out[379]:
0 red;blue;
1 blue;
2 red;
3
dtype: object
#df['msg']=(df!='').dot(df.columns).replace({'A':'red;','B':'blue;'},regex=True)
Questions connexes
De nouvelles questions
python
Python est un langage de programmation multi-paradigme, typé dynamiquement et polyvalent. Il est conçu pour être rapide à apprendre, comprendre, utiliser et appliquer une syntaxe propre et uniforme. Veuillez noter que Python 2 est officiellement hors support à partir du 01-01-2020. Néanmoins, pour les questions Python spécifiques à la version, ajoutez la balise [python-2.7] ou [python-3.x]. Lorsque vous utilisez une variante Python (par exemple, Jython, PyPy) ou une bibliothèque (par exemple, Pandas et NumPy), veuillez l'inclure dans les balises.