web-dev-qa-db-ja.com

他の情報とともに配列またはデータフレームをファイルに保存する

統計ソフトウェア Stata を使用すると、短いテキストスニペットをデータセット内に保存できます。これは、 notes および/または characteristics を使用して実行されます。

これは、リマインダーやTo Doリストから、データの生成方法や特定の変数の推定方法などの情報まで、さまざまな情報を保存できるため、非常に価値のある機能です。

Python 3.6。で同様の機能を考えようとしています。これまでのところ、私はオンラインで調べ、多くの投稿を調べましたが、それは私がやりたいことを正確に扱っていません。

いくつかの参照投稿が含まれます:

小さなNumPy配列の場合、関数 numpy.savez()dictionaryの組み合わせにより、関連するすべての情報を適切に格納できると結論付けました。単一ファイル。

例えば:

a = np.array([[2,4],[6,8],[10,12]])
d = {"first": 1, "second": "two", "third": 3}

np.savez(whatever_name.npz, a=a, d=d)
data = np.load(whatever_name.npz)

arr = data['a']
dic = data['d'].tolist()

ただし、問題は残ります。

NumPy配列または(大)PandasDataFrameを含むファイルに他の情報を潜在的に組み込むより良い方法はありますか?

私は、あなたが例で持つかもしれない提案の特定のprosconsについて聞くことに特に興味があります。依存関係が少ないほど優れています。

44
Pearly Spencer

多くのオプションがあります。この形式の使用経験があるため、HDF5のみについて説明します。

利点:ポータブル(Pythonの外部で読み取ることができます)、ネイティブ圧縮、メモリ不足機能、メタデータのサポート。

短所:単一の低レベルC APIへの依存、単一ファイルとしてのデータ破損の可能性、データの削除はサイズを自動的に縮小しません。

私の経験では、パフォーマンスと移植性のために、avoidpyTables/HDFStoreは数値データを格納します。代わりに h5py で提供される直感的なインターフェイスを使用できます。

配列を保存する

import h5py, numpy as np

arr = np.random.randint(0, 10, (1000, 1000))

f = h5py.File('file.h5', 'w', libver='latest')  # use 'latest' for performance

dset = f.create_dataset('array', shape=(1000, 1000), data=arr, chunks=(100, 100)
                        compression='gzip', compression_opts=9)

圧縮とチャンキング

多くの圧縮の選択肢があります。 blosclzfは、それぞれ圧縮と解凍のパフォーマンスに適した選択肢です。注gzipはネイティブです。他の圧縮フィルターは、HDF5のインストール時にデフォルトで出荷されない場合があります。

チャンキングは別のオプションであり、メモリ外のデータの読み取り方法と合わせると、パフォーマンスを大幅に向上させることができます。

いくつかの属性を追加

dset.attrs['Description'] = 'Some text snippet'
dset.attrs['RowIndexArray'] = np.arange(1000)

辞書を保存する

for k, v in d.items():
    f.create_dataset('dictgroup/'+str(k), data=v)

メモリ不足アクセス

dictionary = f['dictgroup']
res = dictionary['my_key']

ほとんどのC APIを公開するh5pydocumentation を読むことに代わるものはありませんが、上記からかなりの柔軟性があることがわかるはずです。

22
jpp

ここでは、hdf5ストレージが適切なオプションであることにJPPに同意します。彼のソリューションと私の違いは、私がnumpy配列の代わりにPandasデータフレームを使用していることです。これにより、混合型、マルチレベルのインデックス作成(作業にとって非常に重要な日時インデックス付けも可能)、列ラベル付けが可能になり、異なるデータセットがどのように編成されているかを覚えやすくなるため、データフレームが好ましいです。また、Pandasは多数の組み込み機能を提供します(numpyによく似ています)。 Pandasを使用する別の利点は、組み込みのhdfクリエーター(つまり、pandas.DataFrame.to_hdf)があることです。

データフレームをh5に保存する場合、メタデータのディクショナリも保存するオプションがあります。これは、自分へのメモ、またはデータフレームに保存する必要のない実際のメタデータです(フラグの設定にも使用します、例:{'is_agl':True、 'scale_factor':100、 'already_corrected':Falseなど}。この点で、numpy配列とデータフレームの使用に違いはありません。完全なソリューションについては 私の元の質問と解決策はこちら

7
tnknepp

実用的な方法は、メタデータをNumpy配列内に直接埋め込むことです。利点は、必要に応じて余分な依存関係がなく、コードで非常に簡単に使用できることです。ただし、データを保存するメカニズムが必要なので、これはあなたの質問に完全には答えません。HDF5を使用して jpp のソリューションを使用することをお勧めします。

ndarrayにメタデータを含めるには、 ドキュメント に例があります。基本的に、ndarrayをサブクラス化し、infoまたはmetadataなどのフィールドを追加する必要があります。

それは与えるだろう(上記のリンクからのコード)

import numpy as np

class ArrayWithInfo(np.ndarray):

    def __new__(cls, input_array, info=None):
        # Input array is an already formed ndarray instance
        # We first cast to be our class type
        obj = np.asarray(input_array).view(cls)
        # add the new attribute to the created instance
        obj.info = info
        # Finally, we must return the newly created object:
        return obj

    def __array_finalize__(self, obj):
        # see InfoArray.__array_finalize__ for comments
        if obj is None: return
        self.info = getattr(obj, 'info', None)

numpyを介してデータを保存するには、write関数をオーバーロードするか、別のソリューションを使用する必要があります。

5
Christian

jppの答え​​は非常に包括的で、単にpandas v22寄木細工はcsvに対してほとんど欠点のない非常に便利で高速なオプションです(おそらくコーヒーブレークを受け入れます).

寄木細工を読む

寄せ木張り

執筆時点では、次のことも必要です。

pip install pyarrow

情報の追加に関しては、データに添付されているメタデータがあります

import pyarrow as pa
import pyarrow.parquet as pq
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.normal(size=(1000, 10)))

tab = pa.Table.from_pandas(df)

tab = tab.replace_schema_metadata({'here' : 'it is'})

pq.write_table(tab, 'where_is_it.parq')

pq.read_table('where_is_it.parq')
Pyarrow table
0: double
1: double
2: double
3: double
4: double
5: double
6: double
7: double
8: double
9: double
__index_level_0__: int64
metadata
--------
{b'here': b'it is'}

これをパンダに戻すには:

tab.to_pandas()
3
Darren Brien