8

私は Saddle (saddle.github.io) の作成者であり、pandas と精神的に似た機能を提供します (ただし、JVM 上の Scala で)。pandas の DataFrame の HDF5 シリアル化形式が Saddle のそれと相互運用可能であることを確認しようとしています。現在、サドルで文字列配列のシリアル化を実装しています。だから私の質問は、pandas DataFrame が文字列をどのようにシリアル化するかです。次のように pandas で HDF5 ファイルを作成すると:

from pandas import *
h = HDFStore('tmp.h5')
f = DataFrame({0: [1,2,3], 1: ["a", "b", "c"], 2: [1.5, 2.5, 3.5]})
h.put("f1", f)
h.close()

結果の tmp.h5 ファイルを h5dump すると、文字列ブロック (block2_values) がデータ型 H5T_VLEN および属性として格納されていることがわかります。

 ATTRIBUTE "CLASS" {
    DATATYPE  H5T_STRING {
          STRSIZE 8;
          STRPAD H5T_STR_NULLTERM;
          CSET H5T_CSET_ASCII;
          CTYPE H5T_C_S1;
       }
    DATASPACE  SCALAR
    DATA {
    (0): "VLARRAY"
    }
 }

これは ASCII 文字セットを示唆しています。ただし、エンコードされたバイトは ASCII (つまり、"a"、"b"、"c") に対応していないようです。また、STRSIZE 8 がどこから来たのか気になります。pandas -> pytables -> hdf5 を介して発生する文字列のシリアル化の実装の詳細を明らかにできる人はいますか? (私は自分自身をより深く掘り下げることができる pandas/pytables のコードへのポインターにも満足しています:)

4

1 に答える 1

6

表面上は非常に単純に見えますが、実際には舞台裏ではかなり複雑な例を取り上げました。これにより、最終的に 3 つの異なるデータ ブロック (dtype ごとに 1 つ) が格納され、これらのそれぞれにインデックスとデータが格納されます。

あなたが保存したオブジェクトは、私がフォーマットと呼んでいるものStorerです。つまり、numpy 配列は一度に書き込まれるため、一度書き込まれると変更できません。こちらのドキュメントを参照してください: http://pandas.pydata.org/pandas-docs/dev/io.html#hdf5-pytables

PyTables ドキュメントはこちら: http://pytables.github.io/usersguide/libref/declarative_classes.html#the-atom-class-and-its-descendants

残念ながら、これらの文字列は、この特定の形式のストレージに python pickle として保存されているため、クロスプラットフォームでデコードできるかどうかはわかりません。

より基本的な型を使用して保存され、簡単にエクスポートできるオブジェクトを読むのTableが簡単になります (たとえば、ドキュメントに R へのエクスポートに関するセクションがあります)。

このフォーマットを読んでみてください:

In [2]: df = DataFrame({0: [1,2,3], 1: ["a", "b", "c"], 2: [1.5, 2.5, 3.5]})

In [4]: h = pd.HDFStore('tmp.h5')

In [6]: h.put('df',df, table=True)

In [7]: h.close()

PyTablesptdump -avd tmp.h5ユーティリティを使用すると、次の結果が得られます。< PyTables 3.0.0 (出たばかり)、または py3 (0.11.1 でサポート予定) を読んでいる場合。次に、文字列はすべて utf-8 でエンコードされ、バイトとして書き込まれます。(PyTables 3.0.0) より前では、文字列は ascii として書かれていると思います。

/ (RootGroup) ''
  /._v_attrs (AttributeSet), 4 attributes:
   [CLASS := 'GROUP',
    PYTABLES_FORMAT_VERSION := '2.0',
    TITLE := '',
    VERSION := '1.0']
/df (Group) ''
  /df._v_attrs (AttributeSet), 12 attributes:
   [CLASS := 'GROUP',
    TITLE := '',
    VERSION := '1.0',
    data_columns := [],
    index_cols := [(0, 'index')],
    levels := 1,
    nan_rep := b'nan',
    non_index_axes := b"(lp1\n(I1\n(lp2\ncnumpy.core.multiarray\nscalar\np3\n(cnumpy\ndtype\np4\n(S'i8'\nI0\nI1\ntRp5\n(I3\nS'<'\nNNNI-1\nI-1\nI0\ntbS'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\ntRp6\nag3\n(g5\nS'\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\ntRp7\nag3\n(g5\nS'\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\ntRp8\natp9\na.",
    pandas_type := b'frame_table',
    pandas_version := b'0.10.1',
    table_type := b'appendable_frame',
    values_cols := ['values_block_0', 'values_block_1', 'values_block_2']]
/df/table (Table(3,)) ''
  description := {
  "index": Int64Col(shape=(), dflt=0, pos=0),
  "values_block_0": Float64Col(shape=(1,), dflt=0.0, pos=1),
  "values_block_1": Int64Col(shape=(1,), dflt=0, pos=2),
  "values_block_2": StringCol(itemsize=1, shape=(1,), dflt=b'', pos=3)}
  byteorder := 'little'
  chunkshape := (2621,)
  autoindex := True
  colindexes := {
    "index": Index(6, medium, shuffle, zlib(1)).is_csi=False}
  /df/table._v_attrs (AttributeSet), 19 attributes:
   [CLASS := 'TABLE',
    FIELD_0_FILL := 0,
    FIELD_0_NAME := 'index',
    FIELD_1_FILL := 0.0,
    FIELD_1_NAME := 'values_block_0',
    FIELD_2_FILL := 0,
    FIELD_2_NAME := 'values_block_1',
    FIELD_3_FILL := b'',
    FIELD_3_NAME := 'values_block_2',
    NROWS := 3,
    TITLE := '',
    VERSION := '2.6',
    index_kind := b'integer',
    values_block_0_dtype := b'float64',
    values_block_0_kind := b"(lp1\ncnumpy.core.multiarray\nscalar\np2\n(cnumpy\ndtype\np3\n(S'i8'\nI0\nI1\ntRp4\n(I3\nS'<'\nNNNI-1\nI-1\nI0\ntbS'\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\ntRp5\na.",
    values_block_1_dtype := b'int64',
    values_block_1_kind := b"(lp1\ncnumpy.core.multiarray\nscalar\np2\n(cnumpy\ndtype\np3\n(S'i8'\nI0\nI1\ntRp4\n(I3\nS'<'\nNNNI-1\nI-1\nI0\ntbS'\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\ntRp5\na.",
    values_block_2_dtype := b'string8',
    values_block_2_kind := b"(lp1\ncnumpy.core.multiarray\nscalar\np2\n(cnumpy\ndtype\np3\n(S'i8'\nI0\nI1\ntRp4\n(I3\nS'<'\nNNNI-1\nI-1\nI0\ntbS'\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00'\ntRp5\na."]
  Data dump:
[0] (0, [1.5], [1], [b'a'])
[1] (1, [2.5], [2], [b'b'])
[2] (2, [3.5], [3], [b'c'])

詳細については、オフラインでご連絡いただくことをお勧めします。

于 2013-06-12T00:25:02.427 に答える