Les deux exemples ci-dessous échouent avec la même erreur
df = pd.DataFrame(index=[0, 1, 2], columns=['a', 'b'])
df.loc[0, 'a'] = dict(x=2)
df.iloc[0, 0] = dict(x=2)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-282-62f3ee5ff885> in <module>()
1 # file_map.loc[file_no, 'Q_step_length'] = dict(a=1)
2 df = pd.DataFrame(index=[0, 1, 2], columns=['a', 'b'])
----> 3 df.iloc[0, 0] = dict(x=2)
4 df['a'] = df['a'].apply(lambda x: x[0] if not pd.isnull(x) else x)
5 df
...\lib\site-packages\pandas\core\indexing.py in __setitem__(self, key, value)
177 key = com._apply_if_callable(key, self.obj)
178 indexer = self._get_setitem_indexer(key)
--> 179 self._setitem_with_indexer(indexer, value)
180
181 def _has_valid_type(self, k, axis):
...\lib\site-packages\pandas\core\indexing.py in _setitem_with_indexer(self, indexer, value)
603
604 if isinstance(value, (ABCSeries, dict)):
--> 605 value = self._align_series(indexer, Series(value))
606
607 elif isinstance(value, ABCDataFrame):
...\lib\site-packages\pandas\core\indexing.py in _align_series(self, indexer, ser, multiindex_indexer)
743 return ser.reindex(ax)._values
744
--> 745 raise ValueError('Incompatible indexer with Series')
746
747 def _align_frame(self, indexer, df):
ValueError: Incompatible indexer with Series
Cela fonctionne, mais place une liste dans le dataframe
df[0, 'a'] = [dict(x=2)]
Il est possible d'obtenir le dict directement dans le dataframe en utilisant une construction très inélégante comme celle-ci :
df['a'] = df['a'].apply(lambda x: x[0] if not pd.isnull(x) else x)
Puisqu'il est possible de stocker un dict dans une trame de données, essayer une affectation comme ci-dessus ne devrait pas échouer. Je suis conscient que df.loc[...] = dict(...) attribuera des valeurs dans le dict aux colonnes correspondantes si elles sont présentes (est-ce documenté ?) et a ses propres problèmes, mais ce comportement ne devrait pas s'appliquer lors de l'accès un emplacement unique de la trame de données
Une trame de données avec un dict à l'intérieur de l'emplacement spécifié.
pd.show_versions()
validation : aucune
Python : 3.5.4.final.0
python-bits : 64
Système d'exploitation : Windows
Version du système d'exploitation : 10
ordinateur : AMD64
processeur : Intel64 famille 6 modèle 58 pas à pas 9, GenuineIntel
ordre des octets : peu
LC_ALL : aucun
LANGUE : Aucune
LOCALE : Aucun.Aucun
pandas : 0.20.3
pytest : aucun
pip : 9.0.1
outils de configuration : 36.5.0
Cyton : 0,26
numérique : 1.13.1
scipy : 0.19.1
xarray : aucun
IPython : 6.1.0
sphinx : Aucun
pigeon : 0.4.1
dateutil : 2.6.1
pytz : 2017.2
bloc: Aucun
goulot d'étranglement : aucun
tableaux : aucun
numexpr : Aucun
plume : Aucune
matplotlib : 2.0.2
openpyxl : Aucun
xlrd : aucun
xlwt : aucun
xlsxwriter : Aucun
lxml : Aucun
bs4 : aucun
html5lib : 0,9999999
sqlalchemy : Aucun
pymysql : aucun
psycopg2 : aucun
jinja2 : 2.9.6
s3fs : aucun
pandas_gbq : aucun
pandas_datareader : aucun
c'est assez non idiomatique, et vous êtes à peu près seul ici. vous pouvez le faire en utilisant simplement une liste/tuple autour de lui
In [14]: df.loc[0, 'a'] = [dict(x=2)]
In [15]: df
Out[15]:
a b
0 [{'x': 2}] NaN
1 NaN NaN
2 NaN NaN
Rencontré le même problème, j'ai eu deux pensées:
Le stockage d'un dict dans un DataFrame est inhabituel, mais il existe des cas valables où le logiciel peut utiliser Pandas comme moyen de représenter et de manipuler des données arbitraires de style clé/valeur où les données sont indexées d'une manière qui a du sens pour la représentation du panneau.
Le comportement selon lequel l'indexation basée sur l'emplacement mettra à jour les colonnes en fonction des clés/valeurs d'un dictionnaire fourni m'a surpris. Il s'agit d'une fonctionnalité pratique intéressante qui a du sens lorsqu'une colonne explicite n'est pas référencée. Par exemple, lors de la fourniture :
df.loc[row, :] = dict(key1=value1, key2=value2)
Il est logique que les clés du dictionnaire soient écrites sous forme de colonnes et que df.loc[row, key1] == value1
. Cependant, lorsque vous fournissez un index de colonne explicite, déduire les colonnes cibles à partir d'un dictionnaire fourni est (pour moi) contre-intuitif. Si je fournis plutôt :
df.loc[row, col] = dict(key=value)
J'indique explicitement que je veux stocker la valeur entière dans la colonne col
, et je m'attendrais à ce que le dictionnaire soit inséré tel quel.
Quoi qu'il en soit, je suis d'accord avec @jreback que c'est quelque peu non idiomatique MAIS je suis sympathique au problème initial soulevé par @andreas-thomik. J'ai rencontré un problème où essayer de stocker un dict dans un élément d'une trame de données en utilisant cette syntaxe avait du sens pour le problème particulier auquel je faisais face, donc il n'est pas entièrement seul avec cette demande.
@aaclayton ceci est lié à #18955 . Nous pourrions/devrions mieux prendre en charge la définition des scalaires des dicts (et d'autres itérables). C'est un peu délicat cependant.
Commentaire le plus utile
Rencontré le même problème, j'ai eu deux pensées:
Le stockage d'un dict dans un DataFrame est inhabituel, mais il existe des cas valables où le logiciel peut utiliser Pandas comme moyen de représenter et de manipuler des données arbitraires de style clé/valeur où les données sont indexées d'une manière qui a du sens pour la représentation du panneau.
Le comportement selon lequel l'indexation basée sur l'emplacement mettra à jour les colonnes en fonction des clés/valeurs d'un dictionnaire fourni m'a surpris. Il s'agit d'une fonctionnalité pratique intéressante qui a du sens lorsqu'une colonne explicite n'est pas référencée. Par exemple, lors de la fourniture :
df.loc[row, :] = dict(key1=value1, key2=value2)
Il est logique que les clés du dictionnaire soient écrites sous forme de colonnes et que
df.loc[row, key1] == value1
. Cependant, lorsque vous fournissez un index de colonne explicite, déduire les colonnes cibles à partir d'un dictionnaire fourni est (pour moi) contre-intuitif. Si je fournis plutôt :df.loc[row, col] = dict(key=value)
J'indique explicitement que je veux stocker la valeur entière dans la colonne
col
, et je m'attendrais à ce que le dictionnaire soit inséré tel quel.Quoi qu'il en soit, je suis d'accord avec @jreback que c'est quelque peu non idiomatique MAIS je suis sympathique au problème initial soulevé par @andreas-thomik. J'ai rencontré un problème où essayer de stocker un dict dans un élément d'une trame de données en utilisant cette syntaxe avait du sens pour le problème particulier auquel je faisais face, donc il n'est pas entièrement seul avec cette demande.