1
votes

Existe-t-il un moyen d'ajouter un nom de colonne dans toutes les lignes d'une trame de données en fonction d'une condition spécifique dans les pandas?

J'ai un dataframe comme:

   Name  Age  Class    Subject     
    A     13   7     Maths, Bio
    B     17   10    English, Physics

Je veux ajouter une nouvelle colonne nommée Subject, qui devrait inclure les noms de colonne (ayant 1) comme valeurs du champ subject, montré ci-dessous :

   Name  Age  Class Maths English Physics Bio Chemistry
    A     13   7      1    None     None   1    None
    B     17   10    None   1        1    None  None

J'ai essayé d'utiliser plusieurs méthodes, mais cela prend plus de temps que d'habitude.


0 commentaires

3 Réponses :


3
votes

Vous pouvez utiliser appliquer avec la fonction lambda .

df['Subject'] = (df == '1').apply(lambda x: ','.join(df.columns[x]), axis=1)
df = df.iloc[:, [0,1,2,-1]]
df
  Name  Age  Class           Subject
0    A   13      7        Maths, Bio
1    B   17     10  English, Physics


0 commentaires

1
votes

Une méthode facile à lire:

subjects = ['Maths', 'English', 'Physics', 'Bio', 'Chemistry']

df['Subject'] = ""
for row in range(len(df.index)):
    output = []
    for i, col in enumerate(df.loc[df.index[row], subjects]):
        if col == 1:
            output.append(str(subjects[i]))
    df.at[df.index[row], 'Subject'] = ", ".join(output)


0 commentaires

2
votes
#extract subjects columns
subjects = df.iloc[:,3:].columns

#identify columns that are not na per row
notnull = df.filter(subjects).notna().to_numpy()

#get the non null columns and assign to subject column
#... still thinking of a non python loop ... glad if anyone can drop a better replacement
df['subjects'] = [subjects[row].str.cat(sep=', ') for row in notnull]

#drop subjects list
df.drop(subjects,axis=1)

    Name    Age Class   subjects
0   A        13   7     Maths, Bio
1   B        17   10    English, Physics

1 commentaires

Méthode soignée! +1