メタ情報/メタデータをパンダDataFrameに追加する


90

いくつかのメタ情報/メタデータをパンダのDataFrameに追加することは可能ですか?

たとえば、データの測定に使用される機器の名前、責任のある機器など。

回避策の1つは、その情報を使用して列を作成することですが、すべての行に1つの情報を格納するのは無駄に思えます。


@ryanjdillonの回答(現在は下部近くに埋め込まれています)に注意してください。これは、更新された実験属性「attrs」に言及しているため、おそらく
JohnE

回答:


85

もちろん、ほとんどのPythonオブジェクトと同様に、新しい属性をpandas.DataFrame:に添付できます。

import pandas as pd
df = pd.DataFrame([])
df.instrument_name = 'Binky'

ただし、あなたがデータフレームに属性を付けることができますが、操作は(のようなデータフレーム上で実行することをgroupbypivotjoinまたはloc新しいデータフレームを返すことがほんの数名に)することなく、添付のメタデータ。Pandasには、DataFrameに添付されたメタデータ伝播 する堅牢な方法がまだありません。

メタデータをファイルに保存することは可能です。メタデータをHDF5ファイルに保存する方法の例はここにあります。


5
楽器名を+1してください!これらの追加の属性をHDFStoreにダンプしようとした経験はありますか?
ダンアラン2013

4
@DanAllan:の場合store = pd.HDFStore(...)、属性はstore.root._v_attrs.key = value。で保存できます。
unutbu 2013

3
これを使用する可能性のある他の人へ:ドキュメントはこれに関するセクションを追加しました。pandas.pydata.org/pandas-docs/dev/cookbook.html#hdfstore
Dan Allan


4
pandas 0.23.1では、辞書、リスト、またはタプルを割り当てて新しい属性を作成すると、警告が表示されます(つまり、を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 = {})。
teichert

13

自分でこの問題に遭遇しただけです。pandas 0.13の時点で、DataFrameには_metadata属性があり、新しいDataFrameを返す関数を通じて存続します。また、シリアル化にも問題なく耐えられるようです(jsonを試しただけですが、hdfもカバーされていると思います)。


16
_metadataはパブリックAPIの一部ではないため、この機能に依存しないことを強くお勧めします。
shoyer 2015年

@Stephanそれについて詳しく教えていただけますか?パブリックAPIの一部であることが重要なのはなぜですか?あなたの声明はバージョン0.15にも当てはまりますか?
TomCho 2015年

1
@TomChoはい、その答えは今日でも当てはまります。特に多次元データ(.attrs
xray

17
_metadata実際にはクラス属性であり、インスタンス属性ではありません。したがってDataFrame、モジュールがロードされたままである限り、新しいインスタンスは以前のインスタンスから継承します。_metadata何にも使用しないでください。+1 for xarray
j08lue 2016

1
_metadata-私の一日を救ったサポートされていない機能!ありがとうございました。
joctee 2018

12

あんまり。@unutbuが言及しているように、メタデータを含む属性をDataFrameクラスに追加することはできますが、多くのDataFrameメソッドは新しいDataFrameを返すため、メタデータは失われます。データフレームを操作する必要がある場合は、メタデータとDataFrameを別のクラスでラップするのが最善のオプションです。GitHubでこのディスカッションを参照してくださいhttps//github.com/pydata/pandas/issues/2485

現在、メタデータをより適切にサポートするMetaDataFrameオブジェクトを追加するためのオープンプルリクエストがあります。


11

pandas 1.0の時点で、おそらく以前は、Dataframe.attrsプロパティがあります。これは実験的なものですが、これはおそらく将来必要になるものです。例えば:

import pandas as pd
df = pd.DataFrame([])
df.attrs['instrument_name'] = 'Binky'

こちらのドキュメント見つけてください

このアウトをしようとto_parquetし、その後from_parquet、持続していないようですので、必ずご使用の場合にそれをチェックアウトすること。


これは興味深いものであり、copy / loc / ilocでは持続するようですが、groupbyでは持続しないようです。
JohnE

単なる提案ですが、おそらくそれを使用する方法の例を示していますか?ドキュメントは基本的に何もありませんが、それをいじってみると、空の辞書として初期化されており、もちろんリストをその中にネストすることはできますが、辞書でなければならないように設定されているようです。例えば。
JohnE

1
このStackoverflowのディスカッションは、必要に応じて寄木細工のファイルにカスタムメタデータを追加する方法を示しているため、役立つ場合があります
rdmolony

1
@rdmolonyそれは素晴らしいです。dataclassメタデータにaを使用し、次にサブクラス化DataFrameして、共有した投稿のようにロード/ダンプを実行するメソッドを作成することは、優れたソリューションになると思います。
ryanjdillon

1
これはいいね。受け入れられた答えとは対照的に、これはピクルスから保存してロードした後の属性を保持します!
CGFoX

8

DataFrameオブジェクトに任意の属性を付加するという一番の答えは良いですが、辞書、リスト、またはタプルを使用すると、「パンダでは新しい属性名を使用して列を作成できません」というエラーが表示されます。次のソリューションは、任意の属性を格納するために機能します。

from types import SimpleNamespace
df = pd.DataFrame()
df.meta = SimpleNamespace()
df.meta.foo = [1,2,3]

また、これをデータフレームのコピー間で保持する場合は、を実行する必要がありますpd.DataFrame._metadata += ["meta"]。この部分は、パンダの属性ではなく、あなたの特定のデータフレームの属性であることに注意してください
BSCAN

df.metaPandasがこの方法で新しい列を生成することを許可しないという警告をトリガーするため、このアプローチは機能しなくなります。
anishtain4

@ anishtain4、Pandas 25.1(約2週間前にリリース)でテストしたところ、このコードは引き続き機能します。df.metaSimpleNamespaceであるため、この警告はトリガーされません。パンダはそれから列を構築しようとはしません。
BSCAN

6

他の回答やコメントで述べられているように、_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

4

これにかなり遅れて来て、I / Oを介して永続化するメタデータが必要な場合にこれが役立つかもしれないと思いました。これを実現するために使用しているh5ioという比較的新しいパッケージがあります。

これにより、HDF5からいくつかの一般的な形式(そのうちの1つはデータフレーム)に対してすばやく読み取り/書き込みを行うことができます。したがって、たとえば、データフレームをディクショナリに配置し、メタデータをディクショナリのフィールドとして含めることができます。例えば:

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...

もう1つのオプションは、X線のようなプロジェクトを調べることです。これは、いくつかの点でより複雑ですが、メタデータを使用でき、DataFrameに変換するのは非常に簡単だと思います。


4

@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

2

私は解決策を探していましたが、パンダのフレームにはプロパティがあることがわかりました attrs

pd.DataFrame().attrs.update({'your_attribute' : 'value'})
frame.attrs['your_attribute']

この属性は、渡すたびに常にフレームに固定されます。


attrsは実験的なものであり、警告なしに変更される可能性がありますが、これは非常に単純な解決策であることに注意してください。attrsが新しいデータフレームに転送されるのだろうか。
Liquidgenius

残念ながら、属性は新しいデータフレームにコピーされません:(
Adam

1

私は同じ問題を抱えていて、メタデータを使用して辞書から新しい、より小さなDFを作成する回避策を使用しました。

    meta = {"name": "Sample Dataframe", "Created": "19/07/2019"}
    dfMeta = pd.DataFrame.from_dict(meta, orient='index')

このdfMetaは、元のDFと一緒にピクルスなどに保存できます。

複数のオブジェクトをpickleファイルに保存およびロードするを参照してください(Lutzの回答)pickleを使用して複数のデータフレームを保存および取得する際の優れた回答

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.