J'ai un dataframe et un dictionnaire. J'ai besoin d'ajouter une nouvelle colonne au cadre de données et de calculer ses valeurs en fonction du dictionnaire.
Apprentissage automatique, ajout d'une nouvelle fonctionnalité basée sur un tableau:
score = {(1, 45, 1, 1) : 4, (0, 1, 2, 1) : 5}
df = pd.DataFrame(data = {
'gender' : [1, 1, 0, 1, 1, 0, 0, 0, 1, 0],
'age' : [13, 45, 1, 45, 15, 16, 16, 16, 15, 15],
'cholesterol' : [1, 2, 2, 1, 1, 1, 1, 1, 1, 1],
'smoke' : [0, 0, 1, 1, 7, 8, 3, 4, 4, 2]},
dtype = np.int64)
print(df, '\n')
df['score'] = 0
df.score = score[(df.gender, df.age, df.cholesterol, df.smoke)]
print(df)
J'attends la sortie suivante:
gender age cholesterol smoke score
0 1 13 1 0 0
1 1 45 2 0 0
2 0 1 2 1 5
3 1 45 1 1 4
4 1 15 1 7 0
5 0 16 1 8 0
6 0 16 1 3 0
7 0 16 1 4 0
8 1 15 1 4 0
9 0 15 1 2 0
python
pandas
dataframe
dictionary
Mikola
la source
la source
MultiIIndex
. Alternative:df['score'] =df.set_index(['gender', 'age', 'cholesterol', 'smoke']).index.map(score).fillna(0).to_numpy()
.df
viaset_index
, un nouveauSeries
constructeur via. Bien que vous bénéficiez d'un alignement d'index lorsque vous l'affectez àdf['score']
. Enfin,fillna(0, downcast='infer')
fait le travail mais personne ne devrait préférer cette longue solution avec la création de nombreux objets pandas inutilement.merge
pourrait accomplir. J'ai pensé que la réponse serait publiée rapidement, alors j'ai opté pour une alternative et pour une raison quelconque, j'avais MultiIndices en tête. Je suis d'accord, cela ne devrait probablement pas être la réponse acceptée, alors j'espère que cela ne se produira pas.Utilisation
assign
avec une compréhension de liste, obtention d'un tuple de valeurs (chaque ligne) duscore
dictionnaire, par défaut à zéro s'il n'est pas trouvé.Timings
Compte tenu de la variété des approches, je pensais qu'il serait intéressant de comparer certains des horaires.
la source
score.get
j'utiliseraisitertuples
ouzip(*map(df.get, df))
... Pour réitérer, c'est mon approche préférée.df.assign(score=[score.get(t, 0) for t in zip(*map(df.get, df))])
1.0
est le même que le hachage, par1
conséquent, les recherches de tuple devraient avoir pour résultat la même réponse. Excuses @Alexander pour tant de commentaires à ce sujet, mais je veux juste que les gens votent davantage parce que ... ils devraient (-:.values
c'est cherzip(*map(df.get, ['col2', 'col1', 'col5']))
ou obtenir des tuples d'une modification dedf
:zip(*map(df.eq(1).get, df))
Vous pouvez utiliser la carte , car le score est un dictionnaire:
Production
Comme alternative, vous pouvez utiliser une compréhension de liste:
la source
Comprendre la liste et la carte:
Production:
la source
reindex
Ou
merge
la source
Peut-être qu'une autre façon serait d'utiliser
.loc[]
:la source
Solution simple en une ligne, Utilisation
get
et partuple
ligne,La solution ci-dessus suppose qu'il n'y a pas de colonnes autres que celles souhaitées dans l'ordre. Sinon, utilisez simplement des colonnes
la source
score.get
est bonne. Cependant, vous devriez préférer une compréhension, à mon avis. Voir les horaires @ Alexander .