web-dev-qa-db-fra.com

Modifier pandas dataframe ligne par ligne

pandas pour python est soigné. J'essaie de remplacer une liste de dictionnaires par un pandas-dataframe. Cependant, je me demande s'il existe un moyen de modifier les valeurs ligne par - ligne dans une boucle for aussi simple?

Voici la version dict non-pandas:

trialList = [
    {'no':1, 'condition':2, 'response':''},
    {'no':2, 'condition':1, 'response':''},
    {'no':3, 'condition':1, 'response':''}
]  # ... and so on

for trial in trialList:
    # Do something and collect response
    trial['response'] = 'the answer!'

... et maintenant trialList contient les valeurs mises à jour car trial y fait référence. Très utile! Mais la liste des dictés est très peu pratique, surtout parce que j'aimerais pouvoir calculer des trucs colonne par colonne qui pandas Excel à.

Donc, étant donné la liste d'essai ci-dessus, je pensais que je pouvais encore l'améliorer en faisant quelque chose comme des pandas:

import pandas as pd    
dfTrials = pd.DataFrame(trialList)  # makes a Nice 3-column dataframe with 3 rows

for trial in dfTrials.iterrows():
   # do something and collect response
   trials[1]['response'] = 'the answer!'

... mais trialList reste inchangé ici. Existe-t-il un moyen simple de mettre à jour les valeurs ligne par ligne, peut-être équivalent à la version dict? Il est important que ce soit ligne par ligne, car il s'agit d'une expérience où les participants sont présentés avec de nombreux essais et diverses données sont collectées sur chaque essai.

14
Jonas Lindeløv

Si vous voulez vraiment des opérations ligne par ligne, vous pouvez utiliser iterrows et loc:

>>> for i, trial in dfTrials.iterrows():
...     dfTrials.loc[i, "response"] = "answer {}".format(trial["no"])
...     
>>> dfTrials
   condition  no  response
0          2   1  answer 1
1          1   2  answer 2
2          1   3  answer 3

[3 rows x 3 columns]

Mais mieux c'est quand vous pouvez vectoriser:

>>> dfTrials["response 2"] = dfTrials["condition"] + dfTrials["no"]
>>> dfTrials
   condition  no  response  response 2
0          2   1  answer 1           3
1          1   2  answer 2           3
2          1   3  answer 3           4

[3 rows x 4 columns]

Et il y a toujours apply:

>>> def f(row):
...     return "c{}n{}".format(row["condition"], row["no"])
... 
>>> dfTrials["r3"] = dfTrials.apply(f, axis=1)
>>> dfTrials
   condition  no  response  response 2    r3
0          2   1  answer 1           3  c2n1
1          1   2  answer 2           3  c1n2
2          1   3  answer 3           4  c1n3

[3 rows x 5 columns]
40
DSM