Pandas _metadata ошибки сохранения DataFrame

Наконец-то я понял, как использовать _metadata из DataFrame, все работает, за исключением того, что я не могу сохранить его, например, в hdf5 или json. Я знаю, что это работает, потому что я копирую фрейм, а атрибуты _metadata копируют поверх атрибутов «не _metadata», но не копируют.

пример

df = pandas.DataFrame #make up a frame to your liking
pandas.DataFrame._metadata = ["testmeta"]
df.testmeta = "testmetaval"
df.badmeta = "badmetaval"
newframe = df.copy()
newframe.testmeta -->outputs "testmetaval"
newframe.badmeta ---> raises attribute error

#json test
df.to_json(Path)
revivedjsonframe = pandas.io.json.read_json(Path)
revivedjsonframe.testmeta ---->raises Attribute Error

#hdf5 test
revivedhdf5frame.testmeta ---> returns None

этот человек https://stackoverflow.com/a/25715719/4473236 говорит, что у него это сработало, но я новичок в этот сайт (и панды) и не может публиковать сообщения в этой теме или спрашивать его напрямую.


person Skorpeo    schedule 20.01.2015    source источник
comment
Насколько я понимаю, copy() не копирует метаданные, может быть, это изменилось, как ни странно, хотя я не вижу вашей ошибки, я получаю вывод 'badmetaval', какую версию python, numpy и pandas вы используете? Я использую python 3.3.5 64-бит, pandas 0.15.2 и numpy 1.9.1.   -  person EdChum    schedule 20.01.2015
comment
Я использую python 2.7.5, остальное то же самое. Я не знаю, почему это сработает, насколько я понимаю, распространяются только атрибуты _metadata. Вы пытались сохранить их в json? Были ли у него атрибуты в файле json?   -  person Skorpeo    schedule 20.01.2015
comment
Да, у меня все еще все работает, поэтому не уверен, в чем может быть проблема, вы можете попробовать версию Python 3?   -  person EdChum    schedule 20.01.2015
comment
не сейчас... странно, что меня действительно сбивает с толку, так это то, почему badmetaval копирует... это будет означать, что эта проблема неактуальна github.com/pydata/pandas/issues/2485   -  person Skorpeo    schedule 20.01.2015
comment
@EdChum: я вижу то же поведение, что и Skorp, используя pandas 0.15.2. Не могли бы вы опубликовать код, который вы используете?   -  person unutbu    schedule 20.01.2015
comment
@unutbu обязательно увидишь мой ответ   -  person EdChum    schedule 20.01.2015


Ответы (2)


Перед _metadata стоит символ подчеркивания, что означает, что он не является частью общедоступного API. Он не предназначен для пользовательского кода — мы можем сломать его в любой будущей версии pandas без предупреждения.

Я бы настоятельно не рекомендовал использовать эту «функцию». На данный момент лучший вариант для сохранения метаданных с помощью DataFrame — это, вероятно, написать собственный класс-оболочку и самостоятельно обрабатывать сохранение.

person shoyer    schedule 20.01.2015
comment
Вы правы в отношении части _metadata. В этом случае поведение df.badmeta, о котором EdChum сообщает выше, очень странное, и он не использует _metadata. Я не уверен, откуда берутся значения или где они хранятся, будучи новичком, я бы беспокоился о том, что каким-то образом добавляется класс, поскольку как еще он может получить значения badmeta? Его не должно существовать, так как он загружает пустой json, но у фрейма данных есть атрибут, которого нет в файле. Какой-то артефакт... Наконец, я хотел бы помочь реализовать эту функциональность метаданных. - person Skorpeo; 21.01.2015
comment
Будете ли вы сломать его и удалить или сломать и заменить на аналогичную функцию?.)) Мне просто нужно сохранить логический флаг вместе с фреймворком данных на диске. Не хочу усложнять (не)маринование - person Winand; 11.11.2015

Это мой код, который работает с использованием 64-битного Python 3.3.3.2.

In [69]:

df = pd.DataFrame() #make up a frame to your liking
pd.DataFrame._metadata = ["testmeta"]
print(pd.DataFrame._metadata)
df.testmeta = "testmetaval"
df.badmeta = "badmetaval"
newframe = df.copy()
print(newframe.testmeta)
print("newframe", newframe.badmeta)
df.to_json(r'c:\data\test.json')
read_json = pd.read_json(r'c:\data\test.json')
read_json.testmeta
print(pd.version.version)
print(np.version.full_version)
Out[69]:

['testmeta']
testmetaval
newframe badmetaval
0.15.2
1.9.1

Содержимое JSON как df:

In [70]:

read_json
Out[70]:
Empty DataFrame
Columns: []
Index: []
In [71]:

read_json.info()
<class 'pandas.core.frame.DataFrame'>
Float64Index: 0 entries
Empty DataFrame

In [72]:

read_json.testmeta
Out[72]:
'testmetaval'

Как ни странно, написанный json - это просто пустые скобки:

{}

что указывало бы на то, что метаданные фактически распространяются строкой оператора: pd.DataFrame._metadata = ["testmeta"]

Кажется, все еще работает, если вы перезаписываете метаданные второго атрибута:

In [75]:

df.testmeta = 'foo'
df2 = pd.DataFrame()
df2.testmeta = 'bar'
read_json = pd.read_json(r'c:\data\test.json')
print(read_json.testmeta)
print(df2.testmeta)
testmetaval
bar
person EdChum    schedule 20.01.2015
comment
Спасибо, что опубликовали это. Какое значение печатает read_json.testmeta? Каково содержимое c:\data\test.json? - person unutbu; 20.01.2015
comment
@unutbu извините, но вывод ipython становится немного странным, когда у вас есть операторы печати, а последний оператор является переменной, я добавил разделитель вывода, который должен ответить на ваш вопрос, я также опубликую содержимое json - person EdChum; 20.01.2015
comment
Подождите, почему мы модифицируем _metadata в самом классе DataFrame? - person DSM; 20.01.2015
comment
@DSM да, это странно, неясно, что ОП намеревается получить, создавая такой мод. - person EdChum; 20.01.2015
comment
Интересно, если вы определите два DataFrames, один с df.testmeta = 'foo', а другой с df2.testmeta = 'bar', а затем определите read_json = pd.read_json(r'c:\data\test.json'), что вернет read_json.testmeta. Откуда ему знать, что нужно искать в df.testmeta, а не в df2.testmeta? - person unutbu; 20.01.2015
comment
Это должно быть ошибка. если в файле json ничего нет, значит что-то не так. Из моего неузнаваемого понимания _metadata просто сообщает pandas, какие атрибуты являются метаданными, тогда каждый кадр должен создавать/назначать эти атрибуты. Вот еще несколько ссылок, которые я использовал в своем путешествии: stackoverflow.com/questions/23200524/, github.com/pydata/ панды/вопросы/6923. Я думаю, я должен выяснить, как сообщить об этом.... - person Skorpeo; 20.01.2015