J'ai créé un Pandas DataFrame
df = DataFrame(index=['A','B','C'], columns=['x','y'])
et j'ai eu ça
xy A NaN NaN B NaN NaN C NaN NaN
Ensuite, je veux attribuer une valeur à une cellule particulière, par exemple pour la ligne «C» et la colonne «x». Je m'attendais à obtenir un tel résultat:
xy 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 seulement NaN
s dans DataFrame.
Aucune suggestion?
df['x']['C']
), utilisezdf.ix['x','C']
.dataframe[column (series)] [row (Series index)]
:, tandis que de nombreuses personnes (y compris moi-même) sont plus habituées à l'dataframe[row][column]
ordre. En tant que programmeur Matlab et R, ce dernier me semble plus intuitif, mais ce n'est apparemment pas la façon dont Pandas fonctionne ..Réponses:
La réponse de RukTech ,
df.set_value('C', 'x', 10)
est loin plus rapide que les options que je l' ai suggéré ci - dessous. Cependant, il est prévu qu'il soit déprécié .À 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 trame de données avec une copie des données, doncmodifie uniquement cette nouvelle trame de données.
df['x']
renvoie une vue de ladf
trame de données, doncse modifie
df
.Avertissement : Il est parfois difficile de prévoir si une opération renvoie une copie ou une vue. Pour cette raison, les documents recommandent d'éviter les affectations avec "l'indexation chaînée" .
Donc, l'alternative recommandée est
qui ne modifie
df
.la source
df.x
dans l' API . Que voulais-tu dire?'x'
est le nom d'une colonne dansdf
.df.x
renvoie unSeries
avec les valeurs dans la colonnex
. Je vais le changerdf['x']
car cette notation fonctionnera avec n'importe quel nom de colonne (contrairement à la notation par points) et je pense que c'est plus clair.df.x
avait une nouvelle méthode inconnue aux côtésdf.xs, df.ix
df.xs(..., copy=True)
renvoie une copie, et c'est le comportement par défaut.df.xs(..., copy=False)
renvoie l'original.Mise à jour: la
.set_value
méthode va être déconseillée ..iat/.at
sont de bons remplaçants, malheureusement les pandas fournissent peu de documentationLa façon la plus rapide de le faire est d'utiliser set_value . Cette méthode est ~ 100 fois plus rapide que la
.ix
méthode. Par exemple:df.set_value('C', 'x', 10)
la source
df['x']['C'] = 10
.df=df.append(df.sum(numeric_only=True),ignore_index=True)
?Vous pouvez également utiliser une recherche conditionnelle en utilisant
.loc
comme vu ici:où
<some_column_name
est la colonne que vous souhaitez vérifier la<condition>
variable et<another_column_name>
est la colonne que vous souhaitez ajouter (peut être une nouvelle colonne ou une qui existe déjà).<value_to_add>
est la valeur que vous souhaitez ajouter à cette colonne / ligne.Cet exemple ne fonctionne pas précisément avec la question posée, mais il peut être utile pour quelqu'un qui souhaite ajouter une valeur spécifique en fonction d'une condition.
la source
df.loc[df['age']==3, ['age-group']] = 'toddler'
La méthode recommandée (selon les responsables) pour définir une valeur est la suivante:
L'utilisation de l'indexation chaînée (
df['x']['C']
) peut entraîner des problèmes.Voir:
la source
ix
est obsolète: pandas-docs.github.io/pandas-docs-travis/…Essayez d'utiliser
df.loc[row_index,col_indexer] = value
la source
C'est la seule chose qui a fonctionné pour moi!
En savoir plus
.loc
ici .la source
.loc
remplacé.iat/.at
?at
Similaire àloc
, dans la mesure où les deux fournissent des recherches basées sur des étiquettes. À utiliserat
si vous avez uniquement besoin d'obtenir ou de définir une valeur unique dans un DataFrame ou une série. De padas doc.iat/.at
est la bonne solution. Supposons que vous ayez ce simple data_frame:si nous voulons modifier la valeur de la cellule,
[0,"A"]
u peut utiliser l'une de ces solutions:df.iat[0,0] = 2
df.at[0,'A'] = 2
Et voici un exemple complet comment utiliser
iat
pour obtenir et définir une valeur de cellule:y_train avant:
y_train après avoir appelé la fonction de pré-possession que
iat
changer pour multiplier la valeur de chaque cellule par 2:la source
Pour définir des valeurs, utilisez:
set_value
,ix
sont obsolètes.iloc
etloc
la source
vous pouvez utiliser
.iloc
.la source
df.iloc[[2:8], [0]] = [2,3,4,5,6,7]
ce que la méthodedf.loc()
fait nativement.Dans mon exemple, je viens de le changer dans la cellule sélectionnée
'result' est un dataField avec la colonne 'weight'
la source
set_value()
est obsolète.A partir de la version 0.23.4, Pandas " annonce le futur " ...
Compte tenu de ces conseils, voici une démonstration de la façon de les utiliser:
Références:
la source
Voici un résumé des solutions valides fournies par tous les utilisateurs, pour les trames de données indexées par entier et chaîne.
df.iloc, df.loc et df.at fonctionnent pour les deux types de trames de données, df.iloc ne fonctionne qu'avec des indices entiers de ligne / colonne, df.loc et df.at prennent en charge la définition de valeurs à l'aide de noms de colonne et / ou d'indices entiers .
Lorsque l'index spécifié n'existe pas, df.loc et df.at ajoutent les lignes / colonnes nouvellement insérées au bloc de données existant, mais df.iloc déclenche "IndexError: les indexeurs de position sont hors limites". Un exemple de travail testé en Python 2.7 et 3.7 est le suivant:
la source
J'ai testé et la sortie est un
df.set_value
peu plus rapide, mais la méthode officielledf.at
ressemble à la méthode non obsolète la plus rapide pour le faire.Notez que cela définit la valeur d'une seule cellule. Pour les vecteurs
loc
etiloc
devraient être de meilleures options car ils sont vectorisés.la source
Une façon d'utiliser l'index avec condition est tout d'abord d'obtenir l'index de toutes les lignes qui satisfont votre condition, puis d'utiliser simplement ces index de ligne de plusieurs façons
La condition d'exemple est comme
Ensuite, vous pouvez utiliser ces index de ligne de différentes manières, comme
Tout cela est possible car .index renvoie un tableau d'index que .loc peut utiliser avec l'adressage direct, ce qui évite les traversées encore et encore.
la source
df.loc['c','x']=10
Cela changera la valeur de la c ème ligne et de la x ème colonne.la source
En plus des réponses ci-dessus, voici un benchmark comparant différentes façons d'ajouter des lignes de données à une trame de données déjà existante. Il montre que l'utilisation de at ou set-value est le moyen le plus efficace pour les grandes trames de données (au moins pour ces conditions de test).
Pour le test, une trame de données existante comprenant 100 000 lignes et 1 000 colonnes et des valeurs numpy aléatoires a été utilisée. À cette trame de données, 100 nouvelles lignes ont été ajoutées.
Code voir ci-dessous:
la source
Si vous souhaitez modifier les valeurs non pas pour la ligne entière, mais uniquement pour certaines colonnes:
la source
Depuis la version 0.21.1, vous pouvez également utiliser la
.at
méthode. Il y a quelques différences par rapport à ce.loc
qui est mentionné ici - pandas .at contre .loc , mais c'est plus rapide sur le remplacement à valeur uniquela source
Soo, votre question pour convertir NaN à ['x', C] en valeur 10
la réponse est..
le code alternatif est
la source
Moi aussi, je cherchais ce sujet et j'ai mis au point un moyen d'itérer dans un DataFrame et de le mettre à jour avec les valeurs de recherche d'un deuxième DataFrame. Voici mon code.
la source