Solutions en une ligne ou en pipeline
Je vais me concentrer sur deux choses :
-
L'OP indique clairement
Les noms des colonnes modifiées sont stockés dans une liste, mais je ne sais pas comment remplacer les noms des colonnes.
Je ne veux pas résoudre le problème de savoir comment remplacer '$'
ou supprimer le premier caractère de chaque en-tête de colonne. OP a déjà fait cette étape. Je veux plutôt me concentrer sur le remplacement de l'actuel columns
avec un nouvel objet donné par une liste de noms de colonnes de remplacement.
-
df.columns = new
où new
est la liste des noms des nouvelles colonnes est aussi simple que possible. L'inconvénient de cette approche est qu'elle nécessite d'éditer le fichier de données existant columns
et il n'est pas fait en ligne. Je vais vous montrer quelques façons d'effectuer cette opération par pipelining sans modifier le cadre de données existant.
Setup 1
Pour mettre l'accent sur la nécessité de renommer ou de remplacer les noms de colonnes par une liste préexistante, je vais créer un nouvel exemple de cadre de données. df
avec les noms des colonnes initiales et les nouveaux noms des colonnes non liées.
df = pd.DataFrame({'Jack': [1, 2], 'Mahesh': [3, 4], 'Xin': [5, 6]})
new = ['x098', 'y765', 'z432']
df
Jack Mahesh Xin
0 1 3 5
1 2 4 6
Solution 1
pd.DataFrame.rename
Il a déjà été dit que si vous disposiez d'un dictionnaire mettant en correspondance les anciens noms de colonne avec les nouveaux, vous pouviez utiliser pd.DataFrame.rename
.
d = {'Jack': 'x098', 'Mahesh': 'y765', 'Xin': 'z432'}
df.rename(columns=d)
x098 y765 z432
0 1 3 5
1 2 4 6
Cependant, vous pouvez facilement créer ce dictionnaire et l'inclure dans l'appel à la fonction rename
. Ce qui suit tire parti du fait que, lors de l'itération sur df
nous itérons sur chaque nom de colonne.
# Given just a list of new column names
df.rename(columns=dict(zip(df, new)))
x098 y765 z432
0 1 3 5
1 2 4 6
Cela fonctionne très bien si les noms de vos colonnes d'origine sont uniques. Mais s'ils ne le sont pas, cela ne fonctionne pas.
Configuration 2
Colonnes non uniques
df = pd.DataFrame(
[[1, 3, 5], [2, 4, 6]],
columns=['Mahesh', 'Mahesh', 'Xin']
)
new = ['x098', 'y765', 'z432']
df
Mahesh Mahesh Xin
0 1 3 5
1 2 4 6
Solution 2
pd.concat
en utilisant le keys
argument
Tout d'abord, remarquez ce qui se passe lorsque nous essayons d'utiliser la solution 1 :
df.rename(columns=dict(zip(df, new)))
y765 y765 z432
0 1 3 5
1 2 4 6
Nous n'avons pas cartographié le new
comme noms de colonnes. Nous avons fini par répéter y765
. Au lieu de cela, nous pouvons utiliser le keys
argument de la pd.concat
tout en itérant à travers les colonnes de df
.
pd.concat([c for _, c in df.items()], axis=1, keys=new)
x098 y765 z432
0 1 3 5
1 2 4 6
Solution 3
Reconstruire. Cette option ne doit être utilisée que si vous avez une seule dtype
pour toutes les colonnes. Sinon, vous vous retrouverez avec dtype
object
pour toutes les colonnes et leur reconversion nécessite plus de travail de dictionnaire.
Simple dtype
pd.DataFrame(df.values, df.index, new)
x098 y765 z432
0 1 3 5
1 2 4 6
Mixte dtype
pd.DataFrame(df.values, df.index, new).astype(dict(zip(new, df.dtypes)))
x098 y765 z432
0 1 3 5
1 2 4 6
Solution 4
C'est un tour de passe-passe avec transpose
et set_index
. pd.DataFrame.set_index
nous permet de définir un index en ligne, mais il n'y a pas d'index correspondant. set_columns
. On peut donc transposer, alors set_index
et transposer en arrière. Cependant, le même dtype
versus mixte dtype
La mise en garde de la solution 3 s'applique ici.
Simple dtype
df.T.set_index(np.asarray(new)).T
x098 y765 z432
0 1 3 5
1 2 4 6
Mixte dtype
df.T.set_index(np.asarray(new)).T.astype(dict(zip(new, df.dtypes)))
x098 y765 z432
0 1 3 5
1 2 4 6
Solution 5
Utilisez un lambda
sur pd.DataFrame.rename
qui parcourt chaque élément de new
.
Dans cette solution, nous passons un lambda qui prend x
mais l'ignore ensuite. Il prend également un y
mais ne s'y attend pas. Au lieu de cela, un itérateur est donné comme valeur par défaut et je peux alors l'utiliser pour passer d'un élément à l'autre sans tenir compte de la valeur de la variable x
est.
df.rename(columns=lambda x, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6
Et comme il m'a été signalé par les gens de sopython chat si j'ajoute un *
entre les deux x
et y
Je peux protéger mon y
variable. Bien que, dans ce contexte, je ne pense pas qu'il faille la protéger. Elle mérite tout de même d'être mentionnée.
df.rename(columns=lambda x, *, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6
7 votes
Vous pouvez consulter les documents officiels qui traitent du renommage des étiquettes de colonne : pandas.pydata.org/pandas-docs/stable/guide_utilisateur/text.html