Оба приведенных ниже примера завершаются с одной и той же ошибкой.
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
Это работает, но помещает список в кадр данных
df[0, 'a'] = [dict(x=2)]
Можно получить dict прямо в кадре данных, используя очень неэлегантную конструкцию, подобную этой:
df['a'] = df['a'].apply(lambda x: x[0] if not pd.isnull(x) else x)
Поскольку в фрейме данных можно сохранить dict, попытка присваивания, как указано выше, не должна завершиться неудачей. Я знаю, что df.loc[...] = dict(...) будет присваивать значения в dict соответствующим столбцам, если они присутствуют (это задокументировано?) и имеет свои собственные проблемы, но это поведение не должно применяться при доступе единственное расположение фрейма данных
Фрейм данных с словарем внутри указанного местоположения.
pd.show_versions()
фиксация: нет
питон: 3.5.4.финал.0
биты питона: 64
ОС: Windows
ОС-выпуск: 10
машина: AMD64
процессор: Intel64 Family 6 Model 58 Stepping 9, GenuineIntel
порядок байтов: маленький
LC_ALL: нет
ЯЗЫК: Нет
МЕСТОПОЛОЖЕНИЕ: Нет. Нет
панды: 0.20.3
Питест: Нет
пункт: 9.0.1
инструменты настройки: 36.5.0
Цитон: 0,26
номер: 1.13.1
сценарий: 0.19.1
рентген: нет
IPython: 6.1.0
сфинкс: нет
патси: 0.4.1
датаутилит: 2.6.1
питц: 2017.2
блок: нет
узкое место: нет
столы: нет
числовое выражение: нет
перо: нет
матплотлиб: 2.0.2
openpyxl: нет
XLRD: нет
xlwt: нет
xlsxwriter: нет
lxml: нет
бс4: Нет
html5lib: 0.9999999
sqlalchemy: Нет
pymysql: нет
psycopg2: нет
Джиндзя2: 2.9.6
s3fs: нет
pandas_gbq: нет
pandas_datareader: нет
это довольно неидиоматично, и здесь вы в значительной степени сами по себе. вы можете сделать это, просто используя список/кортеж вокруг него
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
Столкнулся с такой же проблемой, было два мысли:
Хранение dict в DataFrame необычно, но есть допустимые случаи, когда программное обеспечение может использовать Pandas как способ представления и управления произвольными данными стиля ключ/значение, где данные индексируются таким образом, который имеет смысл для представления панели.
Поведение, при котором индексация на основе местоположения будет обновлять столбцы на основе ключей/значений предоставленного словаря, стало для меня неожиданностью. Это классная удобная функция, которая имеет смысл, когда не используется явная ссылка на столбец. Например, при предоставлении:
df.loc[row, :] = dict(key1=value1, key2=value2)
Имеет смысл, что ключи словаря могут быть записаны как столбцы и что df.loc[row, key1] == value1
. Однако при предоставлении явного индекса столбца вывод целевых столбцов из предоставленного словаря (для меня) нелогичен. Если я вместо этого предоставлю:
df.loc[row, col] = dict(key=value)
Я явно указываю, что хочу сохранить все значение в столбце col
, и я ожидаю, что словарь будет вставлен как есть.
В любом случае, я согласен с @jreback в том, что это несколько неидиоматично, НО я сочувствую первоначальной проблеме, поднятой @andreas-thomik. Я столкнулся с проблемой, когда попытка сохранить dict для элемента кадра данных с использованием этого синтаксиса имела смысл для конкретной проблемы, с которой я столкнулся, поэтому он не совсем один с этим запросом.
@aaclayton это связано с # 18955 . Мы могли бы/должны лучше поддерживать настройку скаляров диктов (и других итераций). Хотя это немного сложно.
Самый полезный комментарий
Столкнулся с такой же проблемой, было два мысли:
Хранение dict в DataFrame необычно, но есть допустимые случаи, когда программное обеспечение может использовать Pandas как способ представления и управления произвольными данными стиля ключ/значение, где данные индексируются таким образом, который имеет смысл для представления панели.
Поведение, при котором индексация на основе местоположения будет обновлять столбцы на основе ключей/значений предоставленного словаря, стало для меня неожиданностью. Это классная удобная функция, которая имеет смысл, когда не используется явная ссылка на столбец. Например, при предоставлении:
df.loc[row, :] = dict(key1=value1, key2=value2)
Имеет смысл, что ключи словаря могут быть записаны как столбцы и что
df.loc[row, key1] == value1
. Однако при предоставлении явного индекса столбца вывод целевых столбцов из предоставленного словаря (для меня) нелогичен. Если я вместо этого предоставлю:df.loc[row, col] = dict(key=value)
Я явно указываю, что хочу сохранить все значение в столбце
col
, и я ожидаю, что словарь будет вставлен как есть.В любом случае, я согласен с @jreback в том, что это несколько неидиоматично, НО я сочувствую первоначальной проблеме, поднятой @andreas-thomik. Я столкнулся с проблемой, когда попытка сохранить dict для элемента кадра данных с использованием этого синтаксиса имела смысл для конкретной проблемы, с которой я столкнулся, поэтому он не совсем один с этим запросом.