Voglio applicare la mia funzione personalizzata (usa una scala if-else) a queste sei colonne (ERI_Hispanic
, ERI_AmerInd_AKNatv
, ERI_Asian
, ERI_Black_Afr.Amer
, ERI_HI_PacIsl
, ERI_White
) in ogni riga del mio dataframe.
Ho provato diversi metodi da altre domande ma ancora non riesco a trovare la risposta giusta per il mio problema. La parte critica di questo è che se la persona è contata come ispanica non può essere contata come qualsiasi altra cosa. Anche se hanno un "1" in un'altra colonna di etnia sono ancora contati come ispanici e non come due o più razze. Allo stesso modo, se la somma di tutte le colonne ERI è maggiore di 1 sono contati come due o più razze e non possono essere contati come un'unica etnia (eccetto ispanici). Speriamo che questo abbia senso. Qualsiasi aiuto sarà molto apprezzato.
È quasi come fare un ciclo for attraverso ogni riga e se ogni record soddisfa un criterio viene aggiunto a una lista ed eliminato dall'originale.
Dal dataframe sottostante ho bisogno di calcolare una nuova colonna basata sulla seguente specifica in SQL:
========================= CRITERIA ===============================
IF [ERI_Hispanic] = 1 THEN RETURN “Hispanic”
ELSE IF SUM([ERI_AmerInd_AKNatv] + [ERI_Asian] + [ERI_Black_Afr.Amer] + [ERI_HI_PacIsl] + [ERI_White]) > 1 THEN RETURN “Two or More”
ELSE IF [ERI_AmerInd_AKNatv] = 1 THEN RETURN “A/I AK Native”
ELSE IF [ERI_Asian] = 1 THEN RETURN “Asian”
ELSE IF [ERI_Black_Afr.Amer] = 1 THEN RETURN “Black/AA”
ELSE IF [ERI_HI_PacIsl] = 1 THEN RETURN “Haw/Pac Isl.”
ELSE IF [ERI_White] = 1 THEN RETURN “White”
Commento: Se il flag ERI per l'ispanico è vero (1), il dipendente è classificato come "ispanico".
Commento: Se più di 1 flag ERI non ispanico è vero, restituire "Due o più"
====================== DATAFRAME ===========================
lname fname rno_cd eri_afr_amer eri_asian eri_hawaiian eri_hispanic eri_nat_amer eri_white rno_defined
0 MOST JEFF E 0 0 0 0 0 1 White
1 CRUISE TOM E 0 0 0 1 0 0 White
2 DEPP JOHNNY 0 0 0 0 0 1 Unknown
3 DICAP LEO 0 0 0 0 0 1 Unknown
4 BRANDO MARLON E 0 0 0 0 0 0 White
5 HANKS TOM 0 0 0 0 0 1 Unknown
6 DENIRO ROBERT E 0 1 0 0 0 1 White
7 PACINO AL E 0 0 0 0 0 1 White
8 WILLIAMS ROBIN E 0 0 1 0 0 0 White
9 EASTWOOD CLINT E 0 0 0 0 0 1 White
OK, due passi per questo - il primo è scrivere una funzione che faccia la traduzione che vuoi - ho messo insieme un esempio basato sul tuo pseudo-codice:
def label_race (row):
if row['eri_hispanic'] == 1 :
return 'Hispanic'
if row['eri_afr_amer'] + row['eri_asian'] + row['eri_hawaiian'] + row['eri_nat_amer'] + row['eri_white'] > 1 :
return 'Two Or More'
if row['eri_nat_amer'] == 1 :
return 'A/I AK Native'
if row['eri_asian'] == 1:
return 'Asian'
if row['eri_afr_amer'] == 1:
return 'Black/AA'
if row['eri_hawaiian'] == 1:
return 'Haw/Pac Isl.'
if row['eri_white'] == 1:
return 'White'
return 'Other'
Potresti voler rivedere questo, ma sembra fare il trucco - nota che il parametro che va nella funzione è considerato un oggetto Serie etichettato "row".
Successivamente, usate la funzione apply in pandas per applicare la funzione - ad esempio
df.apply (lambda row: label_race(row), axis=1)
Notate lo specificatore axis=1, che significa che l'applicazione viene fatta a livello di riga, piuttosto che di colonna. I risultati sono qui:
0 White
1 Hispanic
2 White
3 White
4 Other
5 White
6 Two Or More
7 White
8 Haw/Pac Isl.
9 White
Se siete soddisfatti di questi risultati, eseguitelo di nuovo, salvando i risultati in una nuova colonna del vostro dataframe originale.
df['race_label'] = df.apply (lambda row: label_race(row), axis=1)
Il dataframe risultante assomiglia a questo (scorri a destra per vedere la nuova colonna):
lname fname rno_cd eri_afr_amer eri_asian eri_hawaiian eri_hispanic eri_nat_amer eri_white rno_defined race_label
0 MOST JEFF E 0 0 0 0 0 1 White White
1 CRUISE TOM E 0 0 0 1 0 0 White Hispanic
2 DEPP JOHNNY NaN 0 0 0 0 0 1 Unknown White
3 DICAP LEO NaN 0 0 0 0 0 1 Unknown White
4 BRANDO MARLON E 0 0 0 0 0 0 White Other
5 HANKS TOM NaN 0 0 0 0 0 1 Unknown White
6 DENIRO ROBERT E 0 1 0 0 0 1 White Two Or More
7 PACINO AL E 0 0 0 0 0 1 White White
8 WILLIAMS ROBIN E 0 0 1 0 0 0 White Haw/Pac Isl.
9 EASTWOOD CLINT E 0 0 0 0 0 1 White White
Poiché questo è il primo risultato di Google per 'pandas new column from others', ecco un semplice esempio:
import pandas as pd
# make a simple dataframe
df = pd.DataFrame({'a':[1,2], 'b':[3,4]})
df
# a b
# 0 1 3
# 1 2 4
# create an unattached column with an index
df.apply(lambda row: row.a + row.b, axis=1)
# 0 4
# 1 6
# do same but attach it to the dataframe
df['c'] = df.apply(lambda row: row.a + row.b, axis=1)
df
# a b c
# 0 1 3 4
# 1 2 4 6
Se ottenete il SettingWithCopyWarning
potete farlo anche in questo modo:
fn = lambda row: row.a + row.b # define a function for the new column
col = df.apply(fn, axis=1) # get column data with an index
df = df.assign(c=col.values) # assign values to column 'c'
Fonte: https://stackoverflow.com/a/12555510/243392
E se il vostro nome di colonna include spazi potete usare una sintassi come questa:
df = df.assign(**{'some column name': col.values})
.apply()
prende una funzione come primo parametro; passate la funzione label_race
come tale:
df['race_label'] = df.apply(label_race, axis=1)
Non c'è bisogno di fare una funzione lambda per passare una funzione.