Aggiungi colonna nel dataframe dall'elenco


94

Ho un dataframe con alcune colonne come questa:

A   B   C  
0   
4
5
6
7
7
6
5

I possibili intervalli di valori in A sono solo da 0 a 7 .

Inoltre, ho un elenco di 8 elementi come questo:

List=[2,5,6,8,12,16,26,32]  //There are only 8 elements in this list

Se l'elemento nella colonna A è n , ho bisogno di inserire il n -esimo elemento della lista in una nuova colonna, dire 'D'.

Come posso farlo in una volta sola senza eseguire il loop dell'intero dataframe?

Il dataframe risultante sarebbe simile a questo:

A   B   C   D
0           2
4           12
5           16
6           26
7           32
7           32
6           26
5           16

Nota: il dataframe è enorme e l'iterazione è l'ultima opzione. Ma posso anche organizzare gli elementi in "List" in qualsiasi altra struttura di dati come dict, se necessario.


1
Penso che tu abbia bisogno di un esempio di giocattolo (più piccolo), con il risultato desiderato. Suona un po 'vago.
Andy Hayden

11
Mai e poi mai chiamare una variabile "List". In qualsiasi lingua.
lucid_dreamer

Risposte:


50

IIUC, se trasformi il tuo (sfortunatamente denominato) Listin un ndarray, puoi semplicemente indicizzarlo in modo naturale.

>>> import numpy as np
>>> m = np.arange(16)*10
>>> m[df.A]
array([  0,  40,  50,  60, 150, 150, 140, 130])
>>> df["D"] = m[df.A]
>>> df
    A   B   C    D
0   0 NaN NaN    0
1   4 NaN NaN   40
2   5 NaN NaN   50
3   6 NaN NaN   60
4  15 NaN NaN  150
5  15 NaN NaN  150
6  14 NaN NaN  140
7  13 NaN NaN  130

Qui ne ho costruito uno nuovo m, ma se lo usi m = np.asarray(List), dovrebbe funzionare la stessa cosa: i valori in df.Aselezioneranno gli elementi appropriati di m.


Nota che se stai usando una vecchia versione di numpy, potresti m[df.A.values]doverla usare al suo posto: in passato, numpynon giocavi bene con gli altri e alcuni refactoring pandascausavano alcuni mal di testa. Le cose ora sono migliorate.


Ciao @DSM. Ho capito quello che stai dicendo ma ricevo questo errore: Traceback (most recent call last): File "./b.py", line 24, in <module> d["D"] = m[d.A] IndexError: unsupported iterator index
mane

1
@mane: urf, questo è un vecchio numpybug. Funziona d["D"] = m[d.A.values]per te?
DSM

277

Basta assegnare l'elenco direttamente:

df['new_col'] = mylist

Alternativa
Converti l'elenco in una serie o un array e quindi assegna:

se = pd.Series(mylist)
df['new_col'] = se.values

o

df['new_col'] = np.array(mylist)

3
pykernel_launcher.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy """Entry point for launching an IPython kernel.
Ilya Rusin

@sparrow utilizzerà l' pd.Serieseffetto dtype? Voglio dire, lascerà i float come float e le stringhe come stringhe? O gli elementi all'interno dell'elenco saranno impostati per default su stringhe?
3kstc

2
@ IlyaRusin, è un falso positivo che può essere ignorato in questo caso. Per maggiori informazioni: stackoverflow.com/questions/20625582/…
sparrow

1
Questo può essere semplificato in: df ['new_col'] = pd.Series (mylist) .values
smartse

15

Una soluzione che migliora quella fantastica di @sparrow.

Lascia che df sia il tuo set di dati e mylist l'elenco con i valori che desideri aggiungere al dataframe.

Supponiamo che tu voglia chiamare semplicemente la tua nuova colonna, new_column

Per prima cosa trasforma l'elenco in una serie:

column_values = pd.Series(mylist)

Quindi utilizzare la funzione di inserimento per aggiungere la colonna. Questa funzione ha il vantaggio di farti scegliere in quale posizione vuoi posizionare la colonna. Nell'esempio seguente posizioneremo la nuova colonna nella prima posizione da sinistra (impostando loc = 0)

df.insert(loc=0, column='new_column', value=column_values)

Questo non funzionerà se hai cambiato i tuoi indici di df in qualcosa di diverso da 1,2,3 ... in tal caso devi aggiungere tra le righe: column_values.index = df.index
Guy s

8

Per prima cosa creiamo il dataframe che avevi, ignorerò le colonne B e C poiché non sono rilevanti.

df = pd.DataFrame({'A': [0, 4, 5, 6, 7, 7, 6,5]})

E la mappatura che desideri:

mapping = dict(enumerate([2,5,6,8,12,16,26,32]))

df['D'] = df['A'].map(mapping)

Fatto!

print df

Produzione:

   A   D
0  0   2
1  4  12
2  5  16
3  6  26
4  7  32
5  7  32
6  6  26
7  5  16

1
Penso che l'OP sappia già come farlo. Secondo la mia lettura, il problema sta costruendo Ddagli elementi di Ae List("Se l'elemento nella colonna A è n, devo inserire l'ennesimo elemento dalla Lista in una nuova colonna, ad esempio 'D'.")
DSM

COSÌ si è trasformato in una sorta di F (* e stato della tata. Grazie a @DSM per il commento ma non ho potuto correggere il post fino a quando non è stato sottoposto a peer review. E poi è stato rifiutato perché era troppo veloce. E poi ero in grado di rivedere la mia modifica. e poi è troppo tardi perché una risposta peggiore (IMHO) è stata "accettata". Quindi ho davvero alcune meta-tate che sono meno che utili !!!!
Phil Cooper

Beh, non posso parlare per le tate, ma scoprirai che il tuo approccio è circa un ordine di grandezza più lento su array lunghi. Sotto altri aspetti, ovviamente, scegliere tra np.array(List)[df.A]e df["A"].map(dict(enumerate(List)))è principalmente una questione di preferenza.
DSM

Ciao Phil, ho visto solo la tua soluzione e il commento di DSM e poi non ci sono più tornato poiché la soluzione di DSM ha funzionato bene per me. Ma ora guardando la tua soluzione, funziona anche tu. Ho eseguito la soluzione di DSM sul mio set di dati di circa 200k voci e viene eseguita in un paio di secondi con tutti gli altri calcoli che ho. Sono totalmente nuovo ai python-panda e personalmente non stavo cercando niente di elegante o eccezionale; qualunque cosa funzionasse andava bene. Ma onestamente, grazie per la soluzione.
criniera

2

Vecchia domanda; ma cerco sempre di usare il codice più veloce!

Avevo una lista enorme con 69 milioni di uint64. np.array () è stato il più veloce per me.

df['hashes'] = hashes
Time spent: 17.034842014312744

df['hashes'] = pd.Series(hashes).values
Time spent: 17.141014337539673

df['key'] = np.array(hashes)
Time spent: 10.724546194076538
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.