Aggiungi colonna con valore costante al dataframe panda [duplicato]


102

Dato un DataFrame:

np.random.seed(0)
df = pd.DataFrame(np.random.randn(3, 3), columns=list('ABC'), index=[1, 2, 3])
df

          A         B         C
1  1.764052  0.400157  0.978738
2  2.240893  1.867558 -0.977278
3  0.950088 -0.151357 -0.103219

Qual è il modo più semplice per aggiungere una nuova colonna contenente un valore costante, ad esempio 0?

          A         B         C  new
1  1.764052  0.400157  0.978738    0
2  2.240893  1.867558 -0.977278    0
3  0.950088 -0.151357 -0.103219    0

Questa è la mia soluzione, ma non so perché inserisca NaN nella colonna "nuova"?

df['new'] = pd.Series([0 for x in range(len(df.index))])

          A         B         C  new
1  1.764052  0.400157  0.978738  0.0
2  2.240893  1.867558 -0.977278  0.0
3  0.950088 -0.151357 -0.103219  NaN

9
se usi un indice va bene. df['new'] = pd.Series([0 for x in range(len(df.index))], index=df.index).
— zach

5
inoltre, una comprensione dell'elenco è del tutto inutile qui. basta fare[0] * len(df.index)
— acushner

@joris, volevo dire che df ['new'] = 0 mostra il motivo corretto di assegnare zeri all'intera colonna, ma non spiega perché il mio primo tentativo inserisce NaN. Questo è stato risposto dal Philip Cloud nella risposta che ho accettato.
— yemu

7
df['new'] = 0
— Fallo

Risposte:


21

Il motivo per cui questo viene inserito NaNin una colonna è perché df.indexe il Indexdel tuo oggetto a destra sono diversi. @zach mostra il modo corretto per assegnare una nuova colonna di zeri. In generale, pandascerca di fare il maggior allineamento possibile degli indici. Uno svantaggio è che quando gli indici non sono allineati si arriva NaNovunque non siano allineati. Gioca con i metodi reindexe alignper ottenere un po 'di intuizione per i lavori di allineamento con oggetti che hanno indici allineati parzialmente, totalmente e non allineati. Ad esempio, ecco come DataFrame.align()funziona con indici parzialmente allineati:

In [7]: from pandas import DataFrame

In [8]: from numpy.random import randint

In [9]: df = DataFrame({'a': randint(3, size=10)})

In [10]:

In [10]: df
Out[10]:
   a
0  0
1  2
2  0
3  1
4  0
5  0
6  0
7  0
8  0
9  0

In [11]: s = df.a[:5]

In [12]: dfa, sa = df.align(s, axis=0)

In [13]: dfa
Out[13]:
   a
0  0
1  2
2  0
3  1
4  0
5  0
6  0
7  0
8  0
9  0

In [14]: sa
Out[14]:
0     0
1     2
2     0
3     1
4     0
5   NaN
6   NaN
7   NaN
8   NaN
9   NaN
Name: a, dtype: float64

10
Non ho votato negativamente ma il tuo codice manca di commenti, rende difficile seguire quello che stai cercando di ottenere nello snippet
— correggere il

8
Questo non risponde davvero alla domanda. OP chiede come aggiungere una nuova colonna contenente un valore costante.
— cs95

Non sono d'accordo che qui ci sia solo una domanda. C'è "Come si assegna un valore costante a una colonna?" così come "Il mio tentativo di farlo non funziona in modo X, perché si comporta in modo imprevisto?" Credo di aver affrontato entrambi i punti, il primo facendo riferimento a un'altra risposta. Si prega di leggere tutto il testo nella mia risposta.
— Phillip Cloud

Penso che il problema sia con la domanda piuttosto che con la tua risposta. Ci sono due domande distinte contenute in questo post e di conseguenza sono necessarie due risposte distinte per rispondere alla domanda. Credo che questo avrebbe dovuto essere contrassegnato come troppo ampio e il poster avrebbe dovuto porre due domande separate.
— Kevin

83

Assegnazione sul posto super semplice: df['new'] = 0

Per la modifica sul posto, eseguire l'assegnazione diretta. Questo incarico viene trasmesso dai panda per ogni riga.

df = pd.DataFrame('x', index=range(4), columns=list('ABC'))
df

   A  B  C
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x

df['new'] = 'y'
# Same as,
# df.loc[:, 'new'] = 'y'
df

   A  B  C new
0  x  x  x   y
1  x  x  x   y
2  x  x  x   y
3  x  x  x   y

Nota per le colonne degli oggetti

Se vuoi aggiungere una colonna di elenchi vuoti, ecco il mio consiglio:

  • Considera di non farlo. objectle colonne sono cattive notizie in termini di prestazioni. Ripensa a come sono strutturati i tuoi dati.
  • Considera l'idea di archiviare i tuoi dati in una struttura di dati sparsa. Ulteriori informazioni: strutture dati sparse
  • Se è necessario memorizzare una colonna di elenchi, assicurarsi di non copiare più volte lo stesso riferimento.

    # Wrong
    df['new'] = [[]] * len(df)
    # Right
    df['new'] = [[] for _ in range(len(df))]
    

Generazione di una copia: df.assign(new=0)

Se invece ti serve una copia, usa DataFrame.assign:

df.assign(new='y')

   A  B  C new
0  x  x  x   y
1  x  x  x   y
2  x  x  x   y
3  x  x  x   y

E, se è necessario assegnare più colonne di questo tipo con lo stesso valore, è semplice come,

c = ['new1', 'new2', ...]
df.assign(**dict.fromkeys(c, 'y'))

   A  B  C new1 new2
0  x  x  x    y    y
1  x  x  x    y    y
2  x  x  x    y    y
3  x  x  x    y    y

Assegnazione di più colonne

Infine, se è necessario assegnare più colonne con valori diversi, è possibile utilizzarle assigncon un dizionario.

c = {'new1': 'w', 'new2': 'y', 'new3': 'z'}
df.assign(**c)

   A  B  C new1 new2 new3
0  x  x  x    w    y    z
1  x  x  x    w    y    z
2  x  x  x    w    y    z
3  x  x  x    w    y    z

18

Con i panda moderni puoi semplicemente fare:

df['new'] = 0

1
Puoi indicare quali risposte specifiche non sono aggiornate? Lasciamo un commento sotto di loro in modo che gli autori abbiano la possibilità di migliorare.
— cs95

1
Fyi l'unica differenza tra questa risposta e la risposta cs95 (AKA, me) è il nome e il valore della colonna. Tutti i pezzi sono lì.
— cs95

1
Non è tanto che siano obsoleti, ma questa risposta è meno prolissa delle altre ed è più facile da leggere.
— Joey

1
@Joey Non posso discutere con questa logica, suppongo che questa risposta sia più adatta a persone che stanno solo cercando di copiare e incollare qualsiasi cosa che funzioni, piuttosto che cercare di capire e imparare di più sulla libreria. Touche.
— cs95

1
@ cs95 sì, la tua risposta consente alle persone di saperne di più. Anche il df ['new'] = 0 evidenziato nel titolo è buono per la leggibilità. Anch'io ho votato al contrario. Meno prolisso di df.apply (lambda x: 0, axis = 1)
— Joey

7

Ecco un altro liner che usa lambda (crea colonna con valore costante = 10)

df['newCol'] = df.apply(lambda x: 10, axis=1)

prima

df
    A           B           C
1   1.764052    0.400157    0.978738
2   2.240893    1.867558    -0.977278
3   0.950088    -0.151357   -0.103219

dopo

df
        A           B           C           newCol
    1   1.764052    0.400157    0.978738    10
    2   2.240893    1.867558    -0.977278   10
    3   0.950088    -0.151357   -0.103219   10

5
df['newCol'] = 10è anche un one liner (ed è più veloce). Qual è il vantaggio di utilizzare applica qui?
— cs95

2
non cercare di competere con te qui, ma solo mostrare un approccio alternativo.
— Grant Shannon

@ cs95 Questo è utile. Volevo creare una nuova colonna in cui ogni valore fosse un elenco vuoto separato. Solo questo metodo funziona.
— Yatharth Agarwal

@YatharthAgarwal Te lo do, ma ha anche senso dato che i panda non sono progettati per funzionare bene con colonne di elenchi.
— cs95

1
@YatharthAgarwal Se è necessario assegnare elenchi vuoti, questa è ancora una soluzione scadente perché utilizza apply. Provadf['new'] = [[] for _ in range(len(df))]
— cs95
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.