Renommer des colonnes spécifiques dans pandas

182

J'ai un dataframe appelé data. Comment renommer le seul en-tête de colonne? Par exemple gdppour log(gdp)?

data =
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7
natsuki_2002
la source
7
Il y a certainement un chevauchement, mais il n'était pas immédiatement clair pour moi de "Renommer les colonnes dans les pandas" que vous pouviez choisir un élément de colonne solitaire pour le renommer. Bien sûr, rétrospectivement, c'est évident, et si j'avais creusé plus profondément, j'aurais probablement compris cela, mais je pense que cette question / réponse est meilleure pour le souligner.
jeremiahbuddha

Réponses:

360
data.rename(columns={'gdp':'log(gdp)'}, inplace=True)

Le renamespectacle qu'il accepte un dict en tant que paramètre pour columnsque vous passiez simplement un dict avec une seule entrée.

Voir aussi lié

EdChum
la source
3
Cela prend très longtemps sur une trame de données volumineuse, donc je crois que cela permet de copier l'ensemble de la trame de données dans la mémoire?
elgehelge
1
@elgehelge cela ne devrait pas faire, la plupart des opérations pandas renverront une copie et certaines accepteront un inplaceparamètre, si elle ignore ce paramètre, alors c'est un bogue, pouvez-vous faire des minutages avec et sans le paramètre, essayez également quelque chose comme new_df = df.rename(columns={'new_name':'old_name'})et voir si cela est plus rapide ou pas
EdChum
1
@ EdChum Merci. La suppression du inplaceparamètre a presque doublé le temps de 14 secondes à 26 secondes. Mais 14 secondes sont encore assez longues juste pour changer de tête ..
elgehelge
2
juste une note, méfiez-vous! si la colonne cible n'existe pas, (mal orthographier le nom ou plus) cela ne fera rien sans erreur ni avertissement.
Amir
1
@Quastiat c'est un peu déprimant pourquoi certaines de ces opérations simples sont juste plus rapides en faisant une compréhension de liste. Fondamentalement cependant, à moins que vous n'ayez un très grand df, cela ne devrait pas vraiment avoir d'importance à moins que vous ne renommiez beaucoup de colonnes sur un grand df
EdChum
27

Une implémentation beaucoup plus rapide serait à utiliser list-comprehensionsi vous devez renommer une seule colonne.

df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]

Si vous devez renommer plusieurs colonnes, utilisez des expressions conditionnelles telles que:

df.columns = ['log(gdp)' if x=='gdp' else 'cap_mod' if x=='cap' else x for x in df.columns]

Ou, construisez un mappage en utilisant a dictionaryet effectuez l' opération list-comprehensionavec elle geten définissant la valeur par défaut comme l'ancien nom:

col_dict = {'gdp': 'log(gdp)', 'cap': 'cap_mod'}   ## key→old name, value→new name

df.columns = [col_dict.get(x, x) for x in df.columns]

Horaires:

%%timeit
df.rename(columns={'gdp':'log(gdp)'}, inplace=True)
10000 loops, best of 3: 168 µs per loop

%%timeit
df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]
10000 loops, best of 3: 58.5 µs per loop
Nickil Maveli
la source
pd.merge_asof()
J'adorerais
14

Comment renommer une colonne spécifique dans pandas?

À partir de la v0.24 +, pour renommer une (ou plusieurs) colonnes à la fois,

Si vous devez renommer TOUTES les colonnes à la fois,

  • DataFrame.set_axis()méthode avec axis=1. Passez une séquence de type liste. Des options sont également disponibles pour la modification sur place.

rename avec axis=1

df = pd.DataFrame('x', columns=['y', 'gdp', 'cap'], index=range(5))
df

   y gdp cap
0  x   x   x
1  x   x   x
2  x   x   x
3  x   x   x
4  x   x   x

Avec 0.21+, vous pouvez maintenant spécifier un axisparamètre avec rename:

df.rename({'gdp':'log(gdp)'}, axis=1)
# df.rename({'gdp':'log(gdp)'}, axis='columns')
    
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

(Notez que ce renamen'est pas en place par défaut, vous devrez donc réattribuer le résultat .)

Cet ajout a été fait pour améliorer la cohérence avec le reste de l'API. Le nouvel axisargument est analogue au columnsparamètre - ils font la même chose.

df.rename(columns={'gdp': 'log(gdp)'})

   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

rename accepte également un rappel qui est appelé une fois pour chaque colonne.

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

   y  g  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x

Pour ce scénario spécifique, vous voudriez utiliser

df.rename(lambda x: 'log(gdp)' if x == 'gdp' else x, axis=1)

Index.str.replace

Semblable à la replaceméthode des chaînes en python, les pandas Index et Series (object dtype uniquement) définissent une str.replaceméthode ("vectorisée") pour le remplacement basé sur les chaînes et les expressions régulières.

df.columns = df.columns.str.replace('gdp', 'log(gdp)')
df
 
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

L'avantage de cela par rapport aux autres méthodes est qu'il str.replaceprend en charge les expressions régulières (activé par défaut). Consultez la documentation pour plus d'informations.


Passer une liste à set_axisavecaxis=1

Appel set_axisavec une liste d'en-tête (s). La liste doit être égale en longueur à la taille des colonnes / index. set_axismute le DataFrame d'origine par défaut, mais vous pouvez spécifier inplace=Falsede renvoyer une copie modifiée.

df.set_axis(['cap', 'log(gdp)', 'y'], axis=1, inplace=False)
# df.set_axis(['cap', 'log(gdp)', 'y'], axis='columns', inplace=False)

  cap log(gdp)  y
0   x        x  x
1   x        x  x
2   x        x  x
3   x        x  x
4   x        x  x

Remarque: dans les versions futures, inplacesera par défaut True.

Chaînage de méthodes
Pourquoi choisir set_axisquand nous avons déjà une manière efficace d'attribuer des colonnes avec df.columns = ...? Comme l'a montré Ted Petrou dans [cette réponse], ( https://stackoverflow.com/a/46912050/4909087 ) set_axisest utile lorsque vous essayez d'enchaîner des méthodes.

Comparer

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

Contre

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()

Le premier est une syntaxe plus naturelle et fluide.

cs95
la source
3

Il existe au moins cinq façons différentes de renommer des colonnes spécifiques dans les pandas, et je les ai énumérées ci-dessous avec des liens vers les réponses originales. J'ai également chronométré ces méthodes et j'ai trouvé qu'elles fonctionnaient à peu près de la même manière (bien que YMMV dépend de votre ensemble de données et de votre scénario). Le cas de test ci-dessous consiste à renommer les colonnes A M N Zen A2 M2 N2 Z2dans une trame de données avec des colonnes Apour Zcontenir un million de lignes.

# Import required modules
import numpy as np
import pandas as pd
import timeit

# Create sample data
df = pd.DataFrame(np.random.randint(0,9999,size=(1000000, 26)), columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))

# Standard way - https://stackoverflow.com/a/19758398/452587
def method_1():
    df_renamed = df.rename(columns={'A': 'A2', 'M': 'M2', 'N': 'N2', 'Z': 'Z2'})

# Lambda function - https://stackoverflow.com/a/16770353/452587
def method_2():
    df_renamed = df.rename(columns=lambda x: x + '2' if x in ['A', 'M', 'N', 'Z'] else x)

# Mapping function - https://stackoverflow.com/a/19758398/452587
def rename_some(x):
    if x=='A' or x=='M' or x=='N' or x=='Z':
        return x + '2'
    return x
def method_3():
    df_renamed = df.rename(columns=rename_some)

# Dictionary comprehension - https://stackoverflow.com/a/58143182/452587
def method_4():
    df_renamed = df.rename(columns={col: col + '2' for col in df.columns[
        np.asarray([i for i, col in enumerate(df.columns) if 'A' in col or 'M' in col or 'N' in col or 'Z' in col])
    ]})

# Dictionary comprehension - https://stackoverflow.com/a/38101084/452587
def method_5():
    df_renamed = df.rename(columns=dict(zip(df[['A', 'M', 'N', 'Z']], ['A2', 'M2', 'N2', 'Z2'])))

print('Method 1:', timeit.timeit(method_1, number=10))
print('Method 2:', timeit.timeit(method_2, number=10))
print('Method 3:', timeit.timeit(method_3, number=10))
print('Method 4:', timeit.timeit(method_4, number=10))
print('Method 5:', timeit.timeit(method_5, number=10))

Production:

Method 1: 3.650640267
Method 2: 3.163998427
Method 3: 2.998530871
Method 4: 2.9918436889999995
Method 5: 3.2436501520000007

Utilisez la méthode la plus intuitive pour vous et la plus simple à implémenter dans votre application.

thdoan
la source