Définir la valeur pour une cellule particulière dans le DataFrame de pandas en utilisant l'index
J'ai créé une base de données pandas
df=DataFrame(index=['A','B','C'], columns=['x','y'])
et a obtenu ce
x y A NaN NaN B NaN NaN C NaN NaN
Ensuite, je veux assigner une valeur à une cellule particulière, par exemple pour la ligne 'C' et la colonne 'x'.
Je m'attendais à obtenir un tel résultat:
x y A NaN NaN B NaN NaN C 10 NaN
avec ce code:
df.xs('C')['x']=10
mais le contenu de df n'a pas changé. C'est encore une fois seule Nan est dans dataframe.
des suggestions?
12 réponses
Ruktech's answer , df.set_value('C', 'x', 10)
, est de loin plus rapide que les options que j'ai suggérées ci-dessous. Cependant, il a été prévu pour la dépréciation .
à l'avenir, la méthode recommandée est .iat/.at
.
pourquoi df.xs('C')['x']=10
ne fonctionne pas:
df.xs('C')
par défaut, renvoie une nouvelle dataframe avec une copie des données, so
df.xs('C')['x']=10
modifie uniquement cette nouvelle base de données.
df['x']
retourne une vue de la df
dataframe, so
df['x']['C'] = 10
modifie df
lui-même.
Warning : il est parfois difficile de prédire si une opération renvoie une copie ou une vue. Pour cette raison, les recommandent d'éviter les assignations avec "indexation enchaînée" .
la variante recommandée est donc
df.at['C', 'x'] = 10
qui does modifier df
.
In [18]: %timeit df.set_value('C', 'x', 10)
100000 loops, best of 3: 2.9 µs per loop
In [20]: %timeit df['x']['C'] = 10
100000 loops, best of 3: 6.31 µs per loop
In [81]: %timeit df.at['C', 'x'] = 10
100000 loops, best of 3: 9.2 µs per loop
Mise À Jour: Le .la méthode set_value va être dépréciée . .iat/.À sont de bons remplacements, malheureusement pandas fournit peu de documentation
la façon la plus rapide de faire ceci est d'utiliser set_value . Cette méthode est environ 100 fois plus rapide que la méthode .ix
. Par exemple:
df.set_value('C', 'x', 10)
vous pouvez également utiliser une recherche conditionnelle en utilisant .loc
comme vu ici:
df.loc[df[<some_column_name>] == <condition>, <another_column_name>] = <value_to_add>
où <some_column_name
est la colonne que vous voulez cocher la variable <condition>
et <another_column_name>
est la colonne que vous voulez ajouter (peut être une nouvelle colonne ou une colonne qui existe déjà). <value_to_add>
est la valeur que vous voulez ajouter à cette colonne/ligne.
cet exemple ne fonctionne pas précisément avec la question en question, mais il pourrait être utile pour quelqu'un veut ajouter une valeur spécifique en fonction d'une condition.
La méthode recommandée (selon les développeurs) pour définir une valeur est:
df.ix['x','C']=10
L'utilisation de" l'indexation enchaînée " ( df['x']['C']
) peut entraîner des problèmes.
voir:
dans mon exemple je le change juste dans la cellule sélectionnée
for index, row in result.iterrows():
if np.isnan(row['weight']):
result.at[index, 'weight'] = 0.0
"résultat" est un champ de données avec la colonne "poids"
si vous voulez changer les valeurs non pas pour la ligne entière, mais seulement pour certaines colonnes:
x = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
x.iloc[1] = dict(A=10, B=-10)
de la version 0.21.1 vous pouvez également utiliser la méthode .at
. Il y a quelques différences par rapport à .loc
comme mentionné ici - pandas .at versus .loc , mais il est plus rapide sur le remplacement de la valeur simple
df.loc['c','x']=10
Cela changera la valeur de c e ligne et
x ème colonne.
moi aussi je cherchais ce sujet et j'ai créé un moyen d'itérer à travers une base de données et de la mettre à jour avec des valeurs de recherche à partir d'une seconde base de données. Voici mon code.
src_df = pd.read_sql_query(src_sql,src_connection)
for index1, row1 in src_df.iterrows():
for index, row in vertical_df.iterrows():
src_df.set_value(index=index1,col=u'etl_load_key',value=etl_load_key)
if (row1[u'src_id'] == row['SRC_ID']) is True:
src_df.set_value(index=index1,col=u'vertical',value=row['VERTICAL'])