pandas créer une nouvelle colonne basée sur les valeurs des autres colonnes

j'ai essayé différentes méthodes d'autres questions, mais ne semble toujours pas trouver la bonne réponse à mon problème. Le point critique est que si la personne est comptée comme Hispanique, elle ne peut pas être comptée comme autre chose. Même s'ils ont un "1" dans une autre colonne d'ethnicité, ils sont quand même comptés comme Hispaniques et non pas comme deux races ou plus. De même, si la somme de toutes les colonnes de L'ERI est supérieure à 1, elles sont comptées comme deux races ou plus et ne peuvent pas être comptées comme une seule race. ethnicité (accepter pour Hispanique). Espérons que cela a du sens. Toute aide sera grandement appréciée.

C'est presque comme faire une boucle pour chaque ligne et si chaque enregistrement répond à un critère ils sont ajoutés à une liste et éliminés de l'original.

à partir du dataframe ci-dessous, je dois calculer une nouvelle colonne basée sur ce qui suit:

========================= CRITÈRES ===============================

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”

commentaire: si le drapeau ERI pour hispanique est vrai (1), alors l'employé est classé comme "Hispanique"

Commentaire: Si plus de 1 non-Hispanique ERI Drapeau sont remplies, le retour "de Deux ou de Plusieurs"

====================== 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
148
demandé sur Bonifacio2 2014-11-12 15:08:12

3 réponses

OK, deux étapes à cela - d'abord est d'écrire une fonction qui fait la traduction que vous voulez - j'ai mis un exemple ensemble basé sur votre pseudo-code:

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'

vous pouvez vouloir passer en revue ceci, mais il semble faire l'astuce - notez que le paramètre entrant dans la fonction est considéré comme un objet de série appelé"row".

ensuite, utilisez la fonction apply dans pandas pour appliquer la fonction - e.g.

df.apply (lambda row: label_race (row),axis=1)

noter le spécificateur axis=1, ce qui signifie que l'application se fait au niveau d'une rangée, plutôt qu'au niveau d'une colonne. Les résultats sont ici:

0           White
1        Hispanic
2           White
3           White
4           Other
5           White
6     Two Or More
7           White
8    Haw/Pac Isl.
9           White

si vous êtes satisfait de ces résultats, exécutez-le à nouveau, en affichant les résultats dans une nouvelle colonne dans votre dataframe d'origine.

df['race_label'] = df.apply (lambda row: label_race (row),axis=1)

la base de données résultante ressemble à ceci (faites défiler vers la droite pour voir la nouvelle colonne):

      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
198
répondu Thomas Kimber 2018-01-18 09:31:11

comme il s'agit du premier résultat Google pour 'pandas nouvelle colonne des autres', voici un exemple simple:

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

Si vous obtenez le SettingWithCopyWarning , vous pouvez le faire de cette façon:

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'

Source: https://stackoverflow.com/a/12555510/243392


et si votre nom de colonne comprend des espaces, vous pouvez utiliser la syntaxe suivante:

df = df.assign(**{'some column name': col.values})

et voici la documentation pour appliquer , et assigner

"
85
répondu Brian Burns 2018-10-02 09:28:17

"151910920 une fonction comme premier paramètre; passer dans le label_race comme ceci:

df['race_label'] = df.apply(label_race, axis=1)

Vous n'avez pas besoin de faire une fonction lambda de passer dans une fonction.

15
répondu Gabrielle Simard-Moore 2018-04-01 17:14:13