Renommer les colonnes dans les pandas

j'ai une base de données utilisant des pandas et des étiquettes de colonne que je dois éditer pour remplacer les étiquettes de colonne originales.

j'aimerais changer les noms de colonne dans une DataFrame A où les noms de colonne originaux sont:

['$a', '$b', '$c', '$d', '$e'] 

à

['a', 'b', 'c', 'd', 'e'].

j'ai les noms de colonne édités stockés dans une liste, mais je ne sais pas comment remplacer les noms de colonne.

1146
demandé sur jmuhlenkamp 2012-07-05 18:21:15

28 réponses

il suffit de l'attribuer à l'attribut .columns :

>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20
1186
répondu eumiro 2012-07-05 14:23:27

utilisez la fonction df.rename() et référez les colonnes à renommer. Toutes les colonnes n'ont pas à être renommées:

df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})
# Or rename the existing DataFrame (rather than creating a copy) 
df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'}, inplace=True)
1947
répondu lexual 2017-11-17 17:39:42

la méthode rename peut prendre une fonction, par exemple:

In [11]: df.columns
Out[11]: Index([u'$a', u'$b', u'$c', u'$d', u'$e'], dtype=object)

In [12]: df.rename(columns=lambda x: x[1:], inplace=True)

In [13]: df.columns
Out[13]: Index([u'a', u'b', u'c', u'd', u'e'], dtype=object)
305
répondu Andy Hayden 2013-05-21 09:58:59

comme indiqué dans http://pandas.pydata.org/pandas-docs/stable/text.html :

df.columns = df.columns.str.replace('$','')
129
répondu kadee 2015-05-30 13:24:05

puisque vous voulez seulement supprimer le signe $ dans tous les noms de colonne, vous pouvez juste faire:

df = df.rename(columns=lambda x: x.replace('$', ''))

ou

df.rename(columns=lambda x: x.replace('$', ''), inplace=True)
116
répondu paulo.filip3 2014-03-26 10:20:45

Pandas De 0,21+ Répondre

il y a eu quelques mises à jour importantes à la colonne Renommer dans la version 0.21.

  • la rename méthode a ajouté le paramètre axis qui peut être réglé sur columns ou 1 . Cette mise à jour rend cette méthode compatible avec le reste de l'API pandas. Il a toujours les paramètres index et columns mais vous n'êtes plus forcé d'utiliser ils.
  • la set_axis méthode avec la inplace définie à False vous permet de renommer toutes les étiquettes d'index ou de colonne avec une liste.

exemples pour Pandas 0.21+

construire une base de données d'échantillon:

df = pd.DataFrame({'$a':[1,2], '$b': [3,4], 
                   '$c':[5,6], '$d':[7,8], 
                   '$e':[9,10]})

   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

utilisant rename avec axis='columns' ou axis=1 1519510920"
df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis='columns')

ou

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis=1)

les deux résultats sont les suivants:

   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10

il est encore possible d'utiliser l'ancienne méthode signature:

df.rename(columns={'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'})

la fonction rename accepte également les fonctions qui seront appliquées à chaque nom de colonne.

df.rename(lambda x: x[1:], axis='columns')

ou

df.rename(lambda x: x[1:], axis=1)

utilisant set_axis avec une liste et inplace=False

You peut fournir une liste à la méthode set_axis qui est égale en longueur au nombre de colonnes (ou index). Actuellement, inplace par défaut True , mais inplace sera par défaut False dans les futures versions.

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis='columns', inplace=False)

ou

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis=1, inplace=False)

pourquoi ne pas utiliser df.columns = ['a', 'b', 'c', 'd', 'e'] ?

il n'y a rien de mal à assigner des colonnes directement comme ceci. Il est parfaitement la bonne solution.

l'avantage d'utiliser set_axis est qu'il peut être utilisé comme partie d'une chaîne de méthode et qu'il renvoie une nouvelle copie de la DataFrame. Sans elle, vous auriez à stocker vos étapes intermédiaires de la chaîne à une autre variable avant de réassigner les colonnes.

# new for pandas 0.21+
df.some_method1()
  .some_method2()
  .set_axis()
  .some_method3()

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()
102
répondu Ted Petrou 2017-11-17 19:31:57
df.columns = ['a', 'b', 'c', 'd', 'e']

Il remplacera l'actuel noms avec les noms que vous fournissez, dans l'ordre que vous fournissez.

68
répondu M PAUL 2018-10-12 05:45:57
old_names = ['$a', '$b', '$c', '$d', '$e'] 
new_names = ['a', 'b', 'c', 'd', 'e']
df.rename(columns=dict(zip(old_names, new_names)), inplace=True)

ainsi vous pouvez éditer manuellement le new_names comme vous le souhaitez. Fonctionne très bien lorsque vous avez besoin de renommer seulement quelques colonnes pour corriger des fautes d'orthographe, accents, supprimer des caractères spéciaux, etc.

54
répondu migloo 2015-05-21 17:54:25

je pense que cette méthode est utile:

df.rename(columns={"old_column_name1":"new_column_name1", "old_column_name2":"new_column_name2"})

cette méthode vous permet de changer le nom des colonnes individuellement.

37
répondu wolfog 2018-04-19 08:08:00

noms de colonne vs noms de série

je voudrais expliquer un peu ce qui se passe derrière les coulisses.

Dataframes sont un ensemble de séries.

série à son tour sont une extension d'un numpy.array

numpy.array s ont un bien .name

C'est le nom de la série. Il est rare que pandas respecte cet attribut, mais il persiste dans les endroits et peut être utilisé pour pirater certains pandas comportements.

nommant la liste des colonnes

beaucoup de réponses ici, parle de "la 151970920" attribut list alors qu'en fait c'est un Series . Cela signifie qu'il possède un attribut .name .

c'est Ce qui arrive si vous décidez de remplir le nom des colonnes Series :

df.columns = ['column_one', 'column_two']
df.columns.names = ['name of the list of columns']
df.index.names = ['name of the index']

name of the list of columns     column_one  column_two
name of the index       
0                                    4           1
1                                    5           2
2                                    6           3

Notez que le nom de l'index vient toujours un colonne inférieure.

artéfacts that linger

l'attribut .name persiste parfois. Si vous mettez df.columns = ['one', 'two'] , alors df.one.name sera 'one' .

si vous mettez df.one.name = 'three' alors df.columns vous donnera encore ['one', 'two'] , et df.one.name vous donnera 'three'

mais

pd.DataFrame(df.one) sera de retour

    three
0       1
1       2
2       3

parce que pandas réutilise le .name du déjà défini Series .

noms de colonnes à niveaux multiples

Pandas a des façons de faire des noms de colonnes multicouches. Il n'y a pas tellement de magie en jeu mais je voulais couvrir cela dans ma réponse aussi puisque je ne vois personne ramasser sur ce ici.

    |one            |
    |one      |two  |
0   |  4      |  1  |
1   |  5      |  2  |
2   |  6      |  3  |

cela est facilement réalisable en mettant des colonnes aux listes, comme ceci:

df.columns = [['one', 'one'], ['one', 'two']]
31
répondu firelynx 2016-09-29 12:30:40

Une ligne ou d'un Pipeline solutions

je vais me concentrer sur deux choses:

  1. OP stipule clairement

    j'ai les noms de colonne édités stockés dans une liste, mais je ne sais pas comment remplacer les noms de colonne.

    Je ne veux pas résoudre le problème de savoir comment remplacer '$' ou rayer le premier caractère de chaque en-tête de colonne. OP a déjà fait cette étape. Au lieu de cela, je veux me concentrer sur le remplacement de l'objet existant columns par un nouvel objet donné une liste de noms de colonne de remplacement.

  2. df.columns = newnew est la liste des nouveaux noms de colonnes est aussi simple qu'il obtient. L'inconvénient de cette approche est qu'elle nécessite la modification de l'existant dataframe columns attribut et il n'est pas fait en ligne. Je vais vous montrer quelques façons d'effectuer ce via un pipeline sans modification de l'existant dataframe.


Setup 1

Pour mettre l'accent sur la nécessité de renommer les noms de colonnes par une liste préexistante, je vais créer un nouveau datagramme df avec les noms de colonnes initiales et les noms de nouvelles colonnes sans rapport.

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 aviez un dictionnaire faisant correspondre les noms des anciennes colonnes aux nouveaux noms de colonnes, vous pourriez 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 le dictionnaire et l'inclure dans l'appel à rename . Le suivant prend avantage 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 vos noms de colonne originaux sont uniques. Mais si ils ne le sont pas, ce qu'il se décompose.


le programme d'Installation 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 l'argument keys 1519560920"

tout d'abord, noter 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é la liste new comme noms de colonnes. Nous avons fini par répéter y765 . Au lieu de cela, nous pouvons utiliser l'argument keys de la fonction 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. Ceci ne doit être utilisé que si vous avez un seul dtype pour toutes les colonnes. Sinon, vous finirez avec dtype object pour toutes les colonnes et leur conversion en arrière nécessite plus de travail de dictionnaire.

Unique 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 une astuce avec transpose et set_index . pd.DataFrame.set_index permet de définir un index en ligne mais il n'y a pas de set_columns correspondant . Donc nous pouvons transposer, puis set_index , et transposer en arrière. Cependant, le même single dtype versus mixte dtype la mise en garde de la solution 3 s'applique ici.

Unique 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 dans pd.DataFrame.rename qui traverse chaque élément de new

Dans ce solution, nous passons une lambda qui prend x mais l'ignore ensuite. Il faut aussi 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 ensuite l'utiliser pour parcourir un cycle à la fois sans égard à ce que la valeur de 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 me l'ont fait remarquer les gens dans sopython chat, si j'ajoute un * entre x et y , je peux protégez ma variable y . Bien que, dans ce contexte, Je ne pense pas qu'il ait besoin de protection. Il est toujours intéressant de mentionner.

df.rename(columns=lambda x, *, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6
28
répondu piRSquared 2017-09-13 09:10:15

DataFrame -- DF.rename () fonctionnera.

df.rename(columns = {'Old Name':'New Name'})

DF est la base de données que vous avez, et le ancien nom est le nom de la colonne vous souhaitez modifier, puis de la Nouveau Nom est le nouveau nom que vous changer. Cette méthode intégrée de DataFrame rend les choses plus faciles.

19
répondu flowera 2017-10-15 16:25:03
df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]})

Si votre nouvelle liste de colonnes dans le même ordre que les colonnes existantes, la mission est simple:

new_cols = ['a', 'b', 'c', 'd', 'e']
df.columns = new_cols
>>> df
   a  b  c  d  e
0  1  1  1  1  1

si vous aviez un dictionnaire sur les noms d'anciennes colonnes pour les nouveaux noms de colonnes, vous pourriez faire ce qui suit:

d = {'$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}
df.columns = df.columns.map(lambda col: d[col])  # Or `.map(d.get)` as pointed out by @PiRSquared.
>>> df
   a  b  c  d  e
0  1  1  1  1  1

si vous n'avez pas de liste ou de dictionnaire cartographique, vous pouvez enlever le symbole $ par une liste de compréhension:

df.columns = [col[1:] if col[0] == '$' else col for col in df]
16
répondu Alexander 2017-09-13 12:24:31

si vous avez le dataframe, df.les colonnes balancent tout dans une liste que vous pouvez manipuler et ensuite réassigner dans votre dataframe comme les noms des colonnes...

columns = df.columns
columns = [row.replace("$","") for row in columns]
df.rename(columns=dict(zip(columns, things)), inplace=True)
df.head() #to validate the output

la meilleure façon? IDK. - Oui.

une meilleure façon d'évaluer toutes les principales techniques mises de l'avant dans les réponses à la question Est d'utiliser ci-dessous cProfile pour gage mémoire et temps d'exécution. @ kadee, @kaitlyn, & @eumiro avait les fonctions avec les délais d'exécution les plus rapides - bien que ces fonctions soient si rapides que nous comparons l'Arrondissement de .000 et .001 secondes pour toutes les réponses. Morale: ma réponse ci-dessus n'est probablement pas la Meilleure façon.

import pandas as pd
import cProfile, pstats, re

old_names = ['$a', '$b', '$c', '$d', '$e']
new_names = ['a', 'b', 'c', 'd', 'e']
col_dict = {'$a': 'a', '$b': 'b','$c':'c','$d':'d','$e':'e'}

df = pd.DataFrame({'$a':[1,2], '$b': [10,20],'$c':['bleep','blorp'],'$d':[1,2],'$e':['texa$','']})

df.head()

def eumiro(df,nn):
    df.columns = nn
    #This direct renaming approach is duplicated in methodology in several other answers: 
    return df

def lexual1(df):
    return df.rename(columns=col_dict)

def lexual2(df,col_dict):
    return df.rename(columns=col_dict, inplace=True)

def Panda_Master_Hayden(df):
    return df.rename(columns=lambda x: x[1:], inplace=True)

def paulo1(df):
    return df.rename(columns=lambda x: x.replace('$', ''))

def paulo2(df):
    return df.rename(columns=lambda x: x.replace('$', ''), inplace=True)

def migloo(df,on,nn):
    return df.rename(columns=dict(zip(on, nn)), inplace=True)

def kadee(df):
    return df.columns.str.replace('$','')

def awo(df):
    columns = df.columns
    columns = [row.replace("$","") for row in columns]
    return df.rename(columns=dict(zip(columns, '')), inplace=True)

def kaitlyn(df):
    df.columns = [col.strip('$') for col in df.columns]
    return df

print 'eumiro'
cProfile.run('eumiro(df,new_names)')
print 'lexual1'
cProfile.run('lexual1(df)')
print 'lexual2'
cProfile.run('lexual2(df,col_dict)')
print 'andy hayden'
cProfile.run('Panda_Master_Hayden(df)')
print 'paulo1'
cProfile.run('paulo1(df)')
print 'paulo2'
cProfile.run('paulo2(df)')
print 'migloo'
cProfile.run('migloo(df,old_names,new_names)')
print 'kadee'
cProfile.run('kadee(df)')
print 'awo'
cProfile.run('awo(df)')
print 'kaitlyn'
cProfile.run('kaitlyn(df)')
15
répondu andrewwowens 2016-09-07 02:24:19
df = df.rename(columns=lambda n: n.replace('$', ''))

est une façon fonctionnelle de résoudre ce

12
répondu lf2225 2018-04-19 08:07:43

une autre façon de remplacer les étiquettes originales des colonnes est de retirer les caractères indésirables (ici '$') des étiquettes originales des colonnes.

cela aurait pu être fait en exécutant une boucle for sur df.colonnes et ajout des colonnes dépouillées à df.colonne.

au lieu de cela , nous pouvons le faire proprement dans un seul énoncé en utilisant la compréhension de liste comme ci-dessous:

df.columns = [col.strip('$') for col in df.columns]

( strip méthode en bandes Python le personnage de début et de la fin de la chaîne.)

11
répondu kait 2017-07-05 13:19:35

je sais que cette question et cette réponse ont été mâchées à mort. Mais j'y ai fait référence pour m'inspirer d'un de mes problèmes . J'ai été capable de le résoudre en utilisant des bits et des morceaux de différentes réponses donc fournir ma réponse au cas où quelqu'un en a besoin.

ma méthode est générique dans laquelle vous pouvez ajouter des délimiteurs supplémentaires par virgule séparant la variable delimiters= et la future-proof it.

Code De Travail:

import pandas as pd
import re


df = pd.DataFrame({'$a':[1,2], '$b': [3,4],'$c':[5,6], '$d': [7,8], '$e': [9,10]})

delimiters = '$'
matchPattern = '|'.join(map(re.escape, delimiters))
df.columns = [re.split(matchPattern, i)[1] for i in df.columns ]

sortie:

>>> df
   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

>>> df
   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10
10
répondu Anil_M 2016-08-04 20:26:50

Real simple il suffit d'utiliser

df.columns = ['Name1', 'Name2', 'Name3'...]

et il assignera les noms de colonne par l'ordre que vous les mettez

9
répondu Thodoris P 2015-11-29 19:22:47

vous pouvez utiliser str.slice pour cela:

df.columns = df.columns.str.slice(1)
9
répondu Anton Protopopov 2016-01-28 17:31:39
8
répondu Yog 2018-08-29 13:35:39

noter que cette approche ne fonctionne pas pour un MultiIndex. Pour un MultiIndex, vous devez faire quelque chose comme ce qui suit:

>>> df = pd.DataFrame({('$a','$x'):[1,2], ('$b','$y'): [3,4], ('e','f'):[5,6]})
>>> df
   $a $b  e
   $x $y  f
0  1  3  5
1  2  4  6
>>> rename = {('$a','$x'):('a','x'), ('$b','$y'):('b','y')}
>>> df.columns = pandas.MultiIndex.from_tuples([
        rename.get(item, item) for item in df.columns.tolist()])
>>> df
   a  b  e
   x  y  f
0  1  3  5
1  2  4  6
7
répondu oxer 2016-08-29 21:27:20

les colonnes renommer dataframe et remplacer le format

import pandas as pd

data = {'year':[2015,2011,2007,2003,1999,1996,1992,1987,1983,1979,1975],
        'team':['Australia','India','Australia','Australia','Australia','Sri Lanka','Pakistan','Australia','India','West Indies','West Indies'],
        }
df = pd.DataFrame(data)

#Rename Columns
df.rename(columns={'year':'Years of Win','team':'Winning Team'}, inplace=True)

#Replace format
df = df.columns.str.replace(' ', '_')
7
répondu Sankar guru 2018-05-18 09:02:02

si vous avez à traiter avec des charges de colonnes nommées par le système de fourniture hors de votre contrôle, j'ai proposé l'approche suivante qui est une combinaison d'une approche générale et des remplacements spécifiques en une seule fois.

je crée d'abord un dictionnaire à partir des noms de colonnes de dataframe en utilisant des expressions regex afin de jeter certains appendices des noms de colonnes et puis j'ajoute des remplacements spécifiques au dictionnaire pour nommer les colonnes de base comme prévu plus tard dans le base de données de réception.

ceci est ensuite appliqué à la base de données en une seule fois.

dict=dict(zip(df.columns,df.columns.str.replace('(:S$|:C1$|:L$|:D$|\.Serial:L$)','')))
dict['brand_timeseries:C1']='BTS'
dict['respid:L']='RespID'
dict['country:C1']='CountryID
dict['pim1:D']='pim_actual'
df.rename(columns=dict, inplace=True)
4
répondu matthhias 2017-06-16 08:27:37

une autre option est de renommer en utilisant une expression régulière:

import pandas as pd
import re

df = pd.DataFrame({'$a':[1,2], '$b':[3,4], '$c':[5,6]})

df = df.rename(columns=lambda x: re.sub('$','',x))
>>> df
   a  b  c
0  1  3  5
1  2  4  6
4
répondu sbha 2018-07-07 02:07:23

essayez ceci. Il travaille pour moi

df.rename(index=str, columns={"$a": "a", "$b": "b", "$c" : "c", "$d" : "d", "$e" : "e"})
3
répondu Nodar Okroshiashvili 2018-04-19 08:07:06

dans le cas où vous ne voulez pas les noms de ligne df.columns = ['a', 'b',index=False]

2
répondu Domnick 2017-11-02 05:17:38

Voici une chouette petite fonction que j'aime utiliser pour réduire tapant:

def rename(data, oldnames, newname): 
    if type(oldnames) == str: #input can be a string or list of strings 
        oldnames = [oldnames] #when renaming multiple columns 
        newname = [newname] #make sure you pass the corresponding list of new names
    i = 0 
    for name in oldnames:
        oldvar = [c for c in data.columns if name in c]
        if len(oldvar) == 0: 
            raise ValueError("Sorry, couldn't find that column in the dataset")
        if len(oldvar) > 1: #doesn't have to be an exact match 
            print("Found multiple columns that matched " + str(name) + " :")
            for c in oldvar:
                print(str(oldvar.index(c)) + ": " + str(c))
            ind = input('please enter the index of the column you would like to rename: ')
            oldvar = oldvar[int(ind)]
        if len(oldvar) == 1:
            oldvar = oldvar[0]
        data = data.rename(columns = {oldvar : newname[i]})
        i += 1 
    return data   

Voici un exemple de comment cela fonctionne:

In [2]: df = pd.DataFrame(np.random.randint(0,10,size=(10, 4)), columns=['col1','col2','omg','idk'])
#first list = existing variables
#second list = new names for those variables
In [3]: df = rename(df, ['col','omg'],['first','ohmy']) 
Found multiple columns that matched col :
0: col1
1: col2

please enter the index of the column you would like to rename: 0

In [4]: df.columns
Out[5]: Index(['first', 'col2', 'ohmy', 'idk'], dtype='object')
2
répondu seeiespi 2018-05-18 23:36:09
Renaming columns while reading the Dataframe: 

>>> df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1]}).rename(columns = 
         {'$a' : 'a','$b':'b','$c':'c'})

Out[1]: 
   a  b  c
0  1  1  1
1
répondu M.r_L 2018-09-29 08:38:08