Comment mettre à jour des valeurs dans une ligne spécifique dans une DataFrame Python Pandas?
avec les méthodes d'indexation nice dans Pandas, Je n'ai aucun problème à extraire des données de différentes façons. D'un autre côté, je suis encore confus sur la façon de changer des données dans une base de données existante.
dans le code suivant j'ai deux DataFrames et mon but est de mettre à jour des valeurs dans une ligne spécifique dans le premier df à partir des valeurs du second DF. Comment puis-je y parvenir?
import pandas as pd
df = pd.DataFrame({'filename' : ['test0.dat', 'test2.dat'],
'm': [12, 13], 'n' : [None, None]})
df2 = pd.DataFrame({'filename' : 'test2.dat', 'n':16}, index=[0])
# this overwrites the first row but we want to update the second
# df.update(df2)
# this does not update anything
df.loc[df.filename == 'test2.dat'].update(df2)
print(df)
donne
filename m n
0 test0.dat 12 None
1 test2.dat 13 None
[2 rows x 3 columns]
mais comment puis-je obtenir ceci:
filename m n
0 test0.dat 12 None
1 test2.dat 13 16
[2 rows x 3 columns]
3 réponses
Alors tout d'abord, pandas mises à jour à l'aide de l'index. Quand une commande update ne met pas à jour quoi que ce soit, cochez à la fois le côté gauche et le côté droit. Si pour une raison quelconque vous êtes trop paresseux pour mettre à jour les indices pour suivre votre logique d'identification, vous pouvez faire quelque chose du genre
>>> df.loc[df.filename == 'test2.dat', 'n'] = df2[df2.filename == 'test2.dat'].loc[0]['n']
>>> df
Out[331]:
filename m n
0 test0.dat 12 None
1 test2.dat 13 16
si vous voulez faire cela pour l'ensemble de la table, je suggère une méthode que je crois supérieure aux précédentes: puisque votre identifiant est filename
, ensemble filename
comme votre index, puis utilisez update()
comme vous le souhaitiez. Les deux merge
et apply()
l'approche comporte des frais généraux inutiles:
>>> df.set_index('filename', inplace=True)
>>> df2.set_index('filename', inplace=True)
>>> df.update(df2)
>>> df
Out[292]:
m n
filename
test0.dat 12 None
test2.dat 13 16
si vous avez une grande dataframe et seulement quelques valeurs de mise à jour, j'utiliserais apply comme ceci:
import pandas as pd
df = pd.DataFrame({'filename' : ['test0.dat', 'test2.dat'],
'm': [12, 13], 'n' : [None, None]})
data = {'filename' : 'test2.dat', 'n':16}
def update_vals(row, data=data):
if row.filename == data['filename']:
row.n = data['n']
return row
df.apply(update_vals, axis=1)
il y a probablement quelques façons de faire ceci, mais une approche serait de fusionner les deux dataframes ensemble sur la colonne filename/m, puis peupler la colonne 'n' À partir de la bonne dataframe si une correspondance était trouvée. Les n_x, n_y dans le code se réfèrent aux images de gauche/droite dans la fusion.
In[100] : df = pd.merge(df1, df2, how='left', on=['filename','m'])
In[101] : df
Out[101]:
filename m n_x n_y
0 test0.dat 12 None NaN
1 test2.dat 13 None 16
In[102] : df['n'] = df['n_y'].fillna(df['n_x'])
In[103] : df = df.drop(['n_x','n_y'], axis=1)
In[104] : df
Out[104]:
filename m n
0 test0.dat 12 None
1 test2.dat 13 16