Можно ли добавить некоторую метаинформацию / метаданные в DataFrame pandas?
Например, название инструмента, используемого для измерения данных, ответственный инструмент и т. Д.
Одним из способов решения этой проблемы было бы создание столбца с этой информацией, но кажется расточительным хранить одну часть информации в каждой строке!
Ответы:
Конечно, как и большинство объектов Python, вы можете прикрепить новые атрибуты к
pandas.DataFrame
:import pandas as pd df = pd.DataFrame([]) df.instrument_name = 'Binky'
Однако следует отметить, что в то время как вы можете прикрепить атрибуты к DataFrame, операции , выполняемые на DataFrame (например
groupby
,pivot
,join
илиloc
назвать только некоторые из них) может вернуть новый DataFrame без метаданных прилагается. У Pandas пока нет надежного метода распространения метаданных, прикрепленных к DataFrames .Возможно сохранение метаданных в файле . Вы можете найти пример того , как для хранения метаданных в файле HDF5 здесь .
источник
store = pd.HDFStore(...)
, тогда атрибуты могут быть сохранены с помощьюstore.root._v_attrs.key = value
.df = pd.DataFrame(); df.meta = {}
ПроизводитUserWarning: Pandas doesn't allow columns to be created via a new attribute name - see https://pandas.pydata.org/pandas-docs/stable/indexing.html#attribute-access
). (Предупреждение не выводится, если атрибут уже был создан, как вdf = pd.DataFrame(); df.meta = ''; df.meta = {}
).Просто столкнулся с этой проблемой сам. Начиная с pandas 0.13, DataFrames имеет атрибут _metadata, который сохраняется через функции, возвращающие новые DataFrames. Также кажется, что сериализация прекрасно переживает (я пробовал только json, но я думаю, что hdf тоже покрыт).
источник
_metadata
не является частью общедоступного API, поэтому я настоятельно рекомендую не полагаться на эту функцию..attrs
являются частью xray API)_metadata
фактически является атрибутом класса, а не атрибутом экземпляра. Таким образом, новыеDataFrame
экземпляры наследуются от предыдущих, пока модуль остается загруженным. Не использовать_metadata
ни для чего. +1 заxarray
!На самом деле, нет. Хотя вы можете добавить атрибуты, содержащие метаданные, в класс DataFrame, как упоминает @unutbu, многие методы DataFrame возвращают новый DataFrame, поэтому ваши метаданные будут потеряны. Если вам нужно манипулировать фреймом данных, лучшим вариантом будет перенос ваших метаданных и DataFrame в другой класс. См. Это обсуждение на GitHub: https://github.com/pydata/pandas/issues/2485
В настоящее время существует открытый запрос на добавление объекта MetaDataFrame, который лучше поддерживает метаданные.
источник
Начиная с pandas 1.0, возможно, раньше, теперь есть
Dataframe.attrs
свойство. Это экспериментально, но, вероятно, это то, что вам понадобится в будущем. Например:import pandas as pd df = pd.DataFrame([]) df.attrs['instrument_name'] = 'Binky'
Найдите это в документации здесь .
Попробуйте это с помощью,
to_parquet
а затемfrom_parquet
, похоже, это не сохраняется, поэтому обязательно проверьте это в своем варианте использования.источник
dataclass
для метаданных, а затемDataFrame
создание подкласса для метода, выполняющего загрузку / сброс, как в сообщении, которым вы поделились, может быть хорошим решением.Главный ответ - прикрепление произвольных атрибутов к объекту DataFrame - это хорошо, но если вы используете словарь, список или кортеж, он выдаст ошибку «Pandas не позволяет создавать столбцы с новым именем атрибута». Следующее решение работает для хранения произвольных атрибутов.
from types import SimpleNamespace df = pd.DataFrame() df.meta = SimpleNamespace() df.meta.foo = [1,2,3]
источник
pd.DataFrame._metadata += ["meta"]
. Обратите внимание, что эта часть является атрибутом Pandas, а не атрибутом вашего конкретногоdf.meta
вызывает предупреждение о том, что Pandas не позволяет создавать новые столбцы таким образом.df.meta
как это SimpleNamespace. Панды не будут пытаться построить из него колонну.Как упоминалось в других ответах и комментариях,
_metadata
не является частью общедоступного API, поэтому определенно не рекомендуется использовать его в производственной среде. Но вы все равно можете использовать его в исследовательском прототипе и заменить, если он перестанет работать. И сейчас он работает сgroupby
/apply
, что очень полезно. Это пример (который я не нашел в других ответах):df = pd.DataFrame([1, 2, 2, 3, 3], columns=['val']) df.my_attribute = "my_value" df._metadata.append('my_attribute') df.groupby('val').apply(lambda group: group.my_attribute)
Выход:
val 1 my_value 2 my_value 3 my_value dtype: object
источник
Придя к этому довольно поздно, я подумал, что это может быть полезно, если вам нужны метаданные для сохранения при вводе-выводе. Есть относительно новый пакет под названием h5io, который я использовал для этого.
Он должен позволить вам выполнять быстрое чтение / запись из HDF5 для нескольких распространенных форматов, одним из которых является фрейм данных. Таким образом, вы можете, например, поместить фрейм данных в словарь и включить метаданные в качестве полей в словарь. Например:
save_dict = dict(data=my_df, name='chris', record_date='1/1/2016') h5io.write_hdf5('path/to/file.hdf5', save_dict) in_data = h5io.read_hdf5('path/to/file.hdf5') df = in_data['data'] name = in_data['name'] etc...
Другой вариант - изучить такой проект, как xray , который в некотором смысле более сложен, но я думаю, что он позволяет использовать метаданные и его довольно легко преобразовать в DataFrame.
источник
Как упоминал @choldgraf, я обнаружил, что xarray является отличным инструментом для прикрепления метаданных при сравнении данных и построении результатов между несколькими фреймами данных.
В своей работе мы часто сравниваем результаты нескольких ревизий прошивки и разных тестовых сценариев, добавить эту информацию очень просто:
df = pd.read_csv(meaningless_test) metadata = {'fw': foo, 'test_name': bar, 'scenario': sc_01} ds = xr.Dataset.from_dataframe(df) ds.attrs = metadata
источник
Я искал решение и обнаружил, что рамка панды имеет свойство
attrs
pd.DataFrame().attrs.update({'your_attribute' : 'value'}) frame.attrs['your_attribute']
Этот атрибут всегда будет прикрепляться к вашему кадру, когда вы его пройдете!
источник
У меня была такая же проблема, и я использовал обходной путь создания нового DF меньшего размера из словаря с метаданными:
meta = {"name": "Sample Dataframe", "Created": "19/07/2019"} dfMeta = pd.DataFrame.from_dict(meta, orient='index')
Затем этот dfMeta можно сохранить вместе с исходным DF в рассоле и т. Д.
См. Раздел Сохранение и загрузка нескольких объектов в файл рассола? (Ответ Лутца) за отличный ответ по сохранению и извлечению нескольких фреймов данных с помощью рассола
источник