Sostituzione dei valori di colonna in un DataFrame panda


141

Sto cercando di sostituire i valori in una colonna di un frame di dati. La colonna ('femmina') contiene solo i valori 'femmina' e 'maschio'.

Ho provato quanto segue:

w['female']['female']='1'
w['female']['male']='0' 

Ma ricevi esattamente la stessa copia dei risultati precedenti.

Idealmente, vorrei ottenere un output che assomigli al seguente ciclo di elementi.

if w['female'] =='female':
    w['female'] = '1';
else:
    w['female'] = '0';

Ho consultato la documentazione di gotchas ( http://pandas.pydata.org/pandas-docs/stable/gotchas.html ) ma non riesco a capire perché non accada nulla.

Qualsiasi aiuto sarà apprezzato.

Risposte:


259

Se ho capito bene, vuoi qualcosa del genere:

w['female'] = w['female'].map({'female': 1, 'male': 0})

(Qui converto i valori in numeri anziché in stringhe contenenti numeri. Puoi convertirli in "1"e "0", se lo desideri davvero, ma non sono sicuro del perché lo desideri.)

Il motivo per cui il tuo codice non funziona è perché l'utilizzo ['female']su una colonna (la seconda 'female'nella tua w['female']['female']) non significa "selezionare le righe in cui il valore è 'femmina'". Significa selezionare le righe in cui l' indice è "femmina", di cui potrebbe non esserci alcuna nel tuo DataFrame.


6
Grazie. Esattamente quello che stavo cercando. Se dovessi mappare "femmina" su 1 e qualsiasi altra cosa su "0". Come funzionerebbe?
Nero,

17
utilizzare questo solo se tutti i valori nella colonna sono indicati nella funzione mappa. I valori delle colonne non specificati nella funzione mappa saranno sostituiti da nan.
Chandra,

1
Consiglierei anche di usare la .locsintassi per evitare SettingWithCopyWarning: pandas.pydata.org/pandas-docs/stable/…
NickBraunagel

2
invece di .map ho usato .replace
JS noob il

Come faccio a sbarazzarsi di "." delle migliaia su due o più colonne, non riesco a capire. grazie mille
M. Mariscal

115

Puoi modificare un sottoinsieme di un dataframe usando loc:

df.loc[<row selection>, <column selection>]

In questo caso:

w.loc[w.female != 'female', 'female'] = 0
w.loc[w.female == 'female', 'female'] = 1

1
Come lo adatterò in modo da non dover selezionare righe specifiche tramite una condizione, ma solo tutte le righe in una colonna particolare? Quindi cambia tutte le celle in una colonna in un valore particolare.
Dhruv Ghulati,

3
@DhruvGhulati, useresti df.loc [:, <selezione colonna>]


38

Leggera variazione:

w.female.replace(['male', 'female'], [1, 0], inplace=True)

19

Questo dovrebbe funzionare anche:

w.female[w.female == 'female'] = 1 
w.female[w.female == 'male']   = 0

11

Puoi anche usare applycon .getie

w['female'] = w['female'].apply({'male':0, 'female':1}.get):

w = pd.DataFrame({'female':['female','male','female']})
print(w)

Dataframe w:

   female
0  female
1    male
2  female

Utilizzo applyper sostituire i valori dal dizionario:

w['female'] = w['female'].apply({'male':0, 'female':1}.get)
print(w)

Risultato:

   female
0       1
1       0
2       1 

Nota: apply con il dizionario dovrebbe essere usato se tutti i possibili valori delle colonne nel frame di dati sono definiti nel dizionario altrimenti, sarà vuoto per quelli non definiti nel dizionario.


8

Questo è molto compatto:

w['female'][w['female'] == 'female']=1
w['female'][w['female'] == 'male']=0

Un altro buono:

w['female'] = w['female'].replace(regex='female', value=1)
w['female'] = w['female'].replace(regex='male', value=0)

Il primo esempio è l'indicizzazione concatenata ed è sconsigliato in quanto non può garantire se il df risultante sia una copia o una vista. Vedi indicizzazione concatenata
Nordle

7

In alternativa c'è la funzione integrata pd.get_dummies per questi tipi di incarichi:

w['female'] = pd.get_dummies(w['female'],drop_first = True)

Questo ti dà un frame di dati con due colonne, una per ogni valore che si presenta in w ['femmina'], di cui lasci cadere la prima (perché puoi inferirla da quella rimasta). La nuova colonna viene automaticamente denominata come stringa sostituita.

Ciò è particolarmente utile se si hanno variabili categoriali con più di due possibili valori. Questa funzione crea tutte le variabili fittizie necessarie per distinguere tra tutti i casi. Fai attenzione quindi a non assegnare l'intero frame di dati a una singola colonna, ma invece, se w ['femmina'] potrebbe essere 'maschio', 'femmina' o 'neutro', fai qualcosa del genere:

w = pd.concat([w, pd.get_dummies(w['female'], drop_first = True)], axis = 1])
w.drop('female', axis = 1, inplace = True)

Quindi ti rimangono due nuove colonne che ti danno il codice fittizio di "femmina" e ti sbarazzi della colonna con le stringhe.


4

Usando Series.mapconSeries.fillna

Se la tua colonna contiene più stringhe che solo femalee male, Series.mapin questo caso fallirà poiché restituirà NaNaltri valori.

Ecco perché dobbiamo concatenarlo con fillna:

Esempio perché .mapnon riesce :

df = pd.DataFrame({'female':['male', 'female', 'female', 'male', 'other', 'other']})

   female
0    male
1  female
2  female
3    male
4   other
5   other
df['female'].map({'female': '1', 'male': '0'})

0      0
1      1
2      1
3      0
4    NaN
5    NaN
Name: female, dtype: object

Per il corretto metodo, catena mapcon fillna, in modo da riempire la NaNcon valori della colonna originale:

df['female'].map({'female': '1', 'male': '0'}).fillna(df['female'])

0        0
1        1
2        1
3        0
4    other
5    other
Name: female, dtype: object

2

C'è anche una funzione pandaschiamata factorizeche puoi usare per fare automaticamente questo tipo di lavoro. Converte le etichette per i numeri: ['male', 'female', 'male'] -> [0, 1, 0]. Vedi questa risposta per maggiori informazioni.


0

Penso che in risposta dovrebbe essere indicato quale tipo di oggetto ottieni in tutti i metodi suggeriti sopra: è Series o DataFrame.

Quando ricevi la colonna per w.female.o w[[2]](dove, supponi, 2 è il numero della tua colonna) otterrai DataFrame. Quindi in questo caso puoi usare metodi come DataFrame .replace.

Quando si utilizza .loco ilocsi tornare Serie e Serie non avere .replacemetodo, quindi si dovrebbe usare metodi come apply, mape così via.

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.