Pandas: Das Speichern eines Diktats in einem DataFrame schlägt fehl

Erstellt am 4. Okt. 2017  ·  3Kommentare  ·  Quelle: pandas-dev/pandas

Codebeispiel, wenn möglich ein kopierfähiges Beispiel

Beide Beispiele unten schlagen mit demselben Fehler fehl

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

Dies funktioniert, platziert jedoch eine Liste in den Datenrahmen

df[0, 'a'] = [dict(x=2)]

Es ist möglich, das Diktat direkt in den Datenrahmen zu bekommen, indem man ein sehr unelegantes Konstrukt wie dieses verwendet:

df['a'] = df['a'].apply(lambda x: x[0] if not pd.isnull(x) else x)

Problembeschreibung

Da es möglich ist, ein Diktat in einem Datenrahmen zu speichern, sollte der Versuch einer Zuweisung wie oben nicht fehlschlagen. Mir ist bewusst, dass df.loc[...] = dict(...) den entsprechenden Spalten Werte im Diktat zuweist, falls vorhanden (ist das dokumentiert?) und seine eigenen Probleme hat, aber dieses Verhalten sollte beim Zugriff nicht gelten eine einzelne Position des Datenrahmens

Erwartete Ausgabe

Ein Datenrahmen mit einem Diktat innerhalb des angegebenen Speicherorts.

Ausgabe von pd.show_versions()

INSTALLIERTE VERSIONEN

verpflichten: Keine
Python: 3.5.4.final.0
Python-Bits: 64
Betriebssystem: Windows
OS-Release: 10
Maschine: AMD64
Prozessor: Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
Bytereihenfolge: wenig
LC_ALL: Keine
LANG: Nein
LOCALE: Keine.Keine

Pandas: 0.20.3
pytest: Keine
Pip: 9.0.1
Setuptools: 36.5.0
Cython: 0,26
numpy: 1.13.1
scipy: 0.19.1
xarray: Nein
IPython: 6.1.0
Sphinx: Nein
Patsy: 0.4.1
dateutil: 2.6.1
pytz: 2017.2
blosc: Nein
Engpass: Keine
Tabellen: Keine
numexpr: Keine
Feder: Keine
matplotlib: 2.0.2
openpyxl: Keine
xlrd: Keine
xlwt: Keine
xlsxwriter: Keine
lxml: Keine
bs4: Keine
html5lib: 0.9999999
sqlalchemy: Keine
pymysql: Keine
psycopg2: Keine
jinja2: 2.9.6
s3fs: Nein
pandas_gbq: Keine
pandas_datareader: Keine

Indexing

Hilfreichster Kommentar

Hatte das gleiche Problem, hatte zwei Gedanken:

Das Speichern eines Diktats in einem DataFrame ist ungewöhnlich, aber es gibt gültige Fälle, in denen Software Pandas verwendet, um beliebige Schlüssel/Wert-Stildaten darzustellen und zu manipulieren, wobei die Daten auf eine Weise indiziert werden, die für die Panel-Darstellung sinnvoll ist.

Das Verhalten, dass die standortbasierte Indizierung Spalten basierend auf den Schlüsseln/Werten eines bereitgestellten Wörterbuchs aktualisiert, war für mich überraschend. Dies ist eine coole Komfortfunktion, die sinnvoll ist, wenn auf eine explizite Spalte nicht verwiesen wird. Zum Beispiel bei der Bereitstellung von:

df.loc[row, :] = dict(key1=value1, key2=value2)

Es macht Sinn, dass die Schlüssel des Wörterbuchs als Spalten geschrieben werden und dass df.loc[row, key1] == value1 . Wenn Sie jedoch einen expliziten Spaltenindex bereitstellen, ist das Ableiten der Zielspalten aus einem bereitgestellten Wörterbuch (für mich) kontraintuitiv. Wenn ich stattdessen liefere:

df.loc[row, col] = dict(key=value)

Ich gebe ausdrücklich an, dass ich den gesamten Wert in der Spalte col speichern möchte, und ich würde erwarten, dass das Wörterbuch so eingefügt wird, wie es ist.

Wie auch immer, ich stimme @jreback zu, dass dies etwas nicht idiomatisch ist, ABER ich habe Verständnis für das ursprüngliche Problem, das von @andreas-thomik aufgeworfen wurde. Ich bin auf ein Problem gestoßen, bei dem der Versuch, ein Diktat mit dieser Syntax in einem Element eines Datenrahmens zu speichern, für das spezielle Problem, mit dem ich konfrontiert war, sinnvoll war, sodass er mit dieser Anfrage nicht ganz allein ist.

Alle 3 Kommentare

das ist ziemlich unidiomatisch, und Sie sind hier ziemlich auf sich allein gestellt. Sie könnten dies tun, indem Sie einfach eine Liste / ein Tupel darum herum verwenden

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

Hatte das gleiche Problem, hatte zwei Gedanken:

Das Speichern eines Diktats in einem DataFrame ist ungewöhnlich, aber es gibt gültige Fälle, in denen Software Pandas verwendet, um beliebige Schlüssel/Wert-Stildaten darzustellen und zu manipulieren, wobei die Daten auf eine Weise indiziert werden, die für die Panel-Darstellung sinnvoll ist.

Das Verhalten, dass die standortbasierte Indizierung Spalten basierend auf den Schlüsseln/Werten eines bereitgestellten Wörterbuchs aktualisiert, war für mich überraschend. Dies ist eine coole Komfortfunktion, die sinnvoll ist, wenn auf eine explizite Spalte nicht verwiesen wird. Zum Beispiel bei der Bereitstellung von:

df.loc[row, :] = dict(key1=value1, key2=value2)

Es macht Sinn, dass die Schlüssel des Wörterbuchs als Spalten geschrieben werden und dass df.loc[row, key1] == value1 . Wenn Sie jedoch einen expliziten Spaltenindex bereitstellen, ist das Ableiten der Zielspalten aus einem bereitgestellten Wörterbuch (für mich) kontraintuitiv. Wenn ich stattdessen liefere:

df.loc[row, col] = dict(key=value)

Ich gebe ausdrücklich an, dass ich den gesamten Wert in der Spalte col speichern möchte, und ich würde erwarten, dass das Wörterbuch so eingefügt wird, wie es ist.

Wie auch immer, ich stimme @jreback zu, dass dies etwas nicht idiomatisch ist, ABER ich habe Verständnis für das ursprüngliche Problem, das von @andreas-thomik aufgeworfen wurde. Ich bin auf ein Problem gestoßen, bei dem der Versuch, ein Diktat mit dieser Syntax in einem Element eines Datenrahmens zu speichern, für das spezielle Problem, mit dem ich konfrontiert war, sinnvoll war, sodass er mit dieser Anfrage nicht ganz allein ist.

@aaclayton dies bezieht sich auf # 18955 . Wir könnten/sollten das Setzen von Skalaren von Diktaten (und anderen Iterablen) besser unterstützen. Es ist allerdings etwas knifflig.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen