web-dev-qa-db-fra.com

Copier toutes les valeurs d'une colonne dans une nouvelle colonne d'un cadre de données pandas

C'est une question très basique, je n'arrive pas à trouver de réponse.

J'ai un tel dataframe, appelé df:

  A     B     C
 a.1   b.1   c.1
 a.2   b.2   c.2
 a.3   b.3   c.3

Ensuite, j'extrais toutes les lignes de df, où la colonne "B" a la valeur "b.2". J'assigne ces résultats à df_2. 

df_2 = df[df['B'] == 'b.2']

df_2 devient:

  A     B     C
 a.2   b.2   c.2

Ensuite, je copie toutes les valeurs de la colonne "B" dans une nouvelle colonne nommée "D". Faire que df_2 devienne: 

  A     B     C     D
 a.2   b.2   c.2   b.2

Quand je réalise une mission comme celle-ci:

df_2['D'] = df_2['B']

Je reçois l'avertissement suivant:

Une valeur tente d'être définie sur une copie d'une tranche d'un DataFrame. Essayer en utilisant .loc [row_indexer, col_indexer] = valeur à la place

Voir les mises en garde dans la documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy


J'ai aussi essayé d'utiliser .loc lors de la création de df_2 comme ceci:

df_2 = df.loc[df['B'] == 'b.2']

Cependant, je reçois toujours l'avertissement. 

Toute aide est grandement appréciée.

20
Justin Buchanan

Vous pouvez simplement assigner la B à la nouvelle colonne, Like -

df['D'] = df['B']

Exemple/Démo -

In [1]: import pandas as pd

In [2]: df = pd.DataFrame([['a.1','b.1','c.1'],['a.2','b.2','c.2'],['a.3','b.3','c.3']],columns=['A','B','C'])

In [3]: df
Out[3]:
     A    B    C
0  a.1  b.1  c.1
1  a.2  b.2  c.2
2  a.3  b.3  c.3

In [4]: df['D'] = df['B']                  #<---What you want.

In [5]: df
Out[5]:
     A    B    C    D
0  a.1  b.1  c.1  b.1
1  a.2  b.2  c.2  b.2
2  a.3  b.3  c.3  b.3

In [6]: df.loc[0,'D'] = 'd.1'

In [7]: df
Out[7]:
     A    B    C    D
0  a.1  b.1  c.1  d.1
1  a.2  b.2  c.2  b.2
2  a.3  b.3  c.3  b.3
37
Anand S Kumar

Le problème est dans la ligne avant celui qui lance l'avertissement. Lorsque vous créez df_2, vous créez une copie d'une tranche d'une trame de données. À la place, lorsque vous créez df_2, utilisez .copy () et vous ne recevrez plus cet avertissement ultérieurement.

df_2 = df[df['B'] == 'b.2'].copy()
12
Alex

Je pense que la méthode d'accès correcte utilise l'index:

df_2.loc[:,'D'] = df_2['B']
1
Luke

Pour faire suite à ces solutions, voici un code utile illustrant:

#
# Copying columns in pandas without slice warning
#
import numpy as np
df = pd.DataFrame(np.random.randn(10, 3), columns=list('ABC'))

#
# copies column B into new column D
df.loc[:,'D'] = df['B']
print df

#
# creates new column 'E' with values -99
# 
# But copy command replaces those where 'B'>0 while others become NaN (not copied)
df['E'] = -99
print df
df['E'] = df[df['B']>0]['B'].copy()
print df

#
# creates new column 'F' with values -99
# 
# Copy command only overwrites values which meet criteria 'B'>0
df['F']=-99
df.loc[df['B']>0,'F'] = df[df['B']>0]['B'].copy()
print df
0
Mark Andersen