3 votes

ajout de valeurs dans une nouvelle colonne basée sur des index avec pandas en python

Je commence tout juste à utiliser les pandas et j'essaie d'ajouter une nouvelle colonne à un cadre de données existant.

J'ai deux cadres de données où l'index d'un cadre de données est lié à une colonne dans un autre cadre de données. Lorsque ces valeurs sont égales, je dois placer la valeur d'une autre colonne du cadre de données source dans une nouvelle colonne de la colonne de destination.

La section de code ci-dessous illustre ce que je veux dire. La partie commentée est ce dont j'ai besoin comme sortie.

Je suppose que j'ai besoin de la .loc[] fonction.

Autre question, mineure : est-ce une mauvaise pratique d'avoir des index non uniques ?

import pandas as pd

d = {'key':['a',  'b', 'c'], 
     'bar':[1, 2, 3]}

d2 = {'key':['a', 'a', 'b'],
      'other_data':['10', '20', '30']}

df = pd.DataFrame(d)
df2 = pd.DataFrame(data = d2)
df2 = df2.set_index('key')

print df2

##    other_data  new_col
##key           
##a            10   1
##a            20   1
##b            30   2

9voto

jezrael Points 290608

Utiliser renommer index par Series :

df2['new'] = df2.rename(index=df.set_index('key')['bar']).index
print (df2)

    other_data  new
key                
a           10    1
a           20    1
b           30    2

Ou map :

df2['new'] = df2.index.to_series().map(df.set_index('key')['bar'])
print (df2)

    other_data  new
key                
a           10    1
a           20    1
b           30    2

Si vous voulez de meilleures performances, le mieux est d'éviter les doublons dans l'index. De plus, certaines fonctions comme reindex a échoué dans l'index des doublons.

3voto

piRSquared Points 159

Vous pouvez utiliser join

df2.join(df.set_index('key'))

    other_data  bar
key                
a           10    1
a           20    1
b           30    2

Une façon de renommer la colonne au cours du processus

df2.join(df.set_index('key').bar.rename('new'))

    other_data  new
key                
a           10    1
a           20    1
b           30    2

2voto

Dark Points 20515

Avec l'aide de .loc

df2['new'] = df.set_index('key').loc[df2.index]

Sortie :

   other\_data  new
key                
a           10    1
a           20    1
b           30    2

2voto

Brad Solomon Points 11873

Une autre question, mineure : est-ce une mauvaise pratique que d'avoir des non uniques ?

Ce n'est pas une grande pratique, mais cela dépend de vos besoins et peut être correct dans certaines circonstances.

Numéro 1 : opérations de jonction

Un bon point de départ est de penser à Qu'est-ce qui différencie un index d'une colonne standard de DataFrame ? . Cela pose la question suivante : si votre index a des valeurs en double, doit-il vraiment être spécifié comme un index, ou peut-il simplement être une autre colonne dans un fichier de type RangeIndex -ed DataFrame ? Si vous avez déjà utilisé SQL ou tout autre DMBS et que vous souhaitez imiter les opérations de jointure dans pandas avec des fonctions telles que .join o .merge vous perdrez la fonctionnalité d'un clé primaire si vous avez des valeurs d'index en double. Une fusion vous donnera ce qui est fondamentalement un produit cartésien - probablement pas ce que vous recherchez.

Par exemple :

df = pd.DataFrame(np.random.randn(10,2),
                  index=2*list('abcde'))
df2 = df.rename(columns={0: 'a', 1 : 'b'})
print(df.merge(df2, left_index=True, right_index=True).head(7))
         0        1        a        b
a  0.73737  1.49073  0.73737  1.49073
a  0.73737  1.49073 -0.25562 -2.79859
a -0.25562 -2.79859  0.73737  1.49073
a -0.25562 -2.79859 -0.25562 -2.79859
b -0.93583  1.17583 -0.93583  1.17583
b -0.93583  1.17583 -1.77153 -0.69988
b -1.77153 -0.69988 -0.93583  1.17583

Question 2 : la performance

Les indices à valeur unique rendent certaines opérations efficaces, comme l'explique le document ce poste.

Lorsque l'index est unique, pandas utilise une table de hachage pour faire correspondre la clé à la valeur O(1). Lorsque l'index est non-unique et trié, les pandas utilisent la recherche binaire O(logN), lorsque l'index est aléatoire et ordonné, les pandas doivent vérifier toutes les clés de l'index l'index O(N).

Un mot sur .loc

Utilisation de .loc retournera toutes les instances de l'étiquette. Cela peut être une bénédiction ou une malédiction en fonction de votre objectif. Par exemple,

df = pd.DataFrame(np.random.randn(10,2),
                  index=2*list('abcde'))
print(df.loc['a'])
         0        1
a  0.73737  1.49073
a -0.25562 -2.79859

1voto

John Galt Points 1144

Utilisation de combine_first

In [442]: df2.combine_first(df.set_index('key')).dropna()
Out[442]:
     bar other_data
key
a    1.0         10
a    1.0         20
b    2.0         30

Ou en utilisant map

In [461]: df2.assign(bar=df2.index.to_series().map(df.set_index('key')['bar']))
Out[461]:
    other_data  bar
key
a           10    1
a           20    1
b           30    2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X