Pandasを使用してjsonから自動的に読み込んだDataFrameを再配置しようとしています。検索しましたが、成功しませんでした。
私は次のjson(コピー/貼り付けの便宜のために文字列として保存されています)を持っており、タグ 'value'の下にjsonオブジェクト/辞書の束があります
json_str = '''{"preferred_timestamp": "internal_timestamp",
"internal_timestamp": 3606765503.684,
"stream_name": "ctdpf_j_cspp_instrument",
"values": [{
"value_id": "temperature",
"value": 9.8319
}, {
"value_id": "conductivity",
"value": 3.58847
}, {
"value_id": "pressure",
"value": 22.963
}]
}'''
Jsonをフラット化されたPandasデータフレームにロードするために、関数 'json_normalize'を使用します。
>>> from pandas.io.json import json_normalize
>>> import simplejson as json
>>> df = json_normalize(json.loads(json_str), 'values', ['preferred_timestamp', 'stream_name', 'internal_timestamp'])
>>> df
value value_id preferred_timestamp internal_timestamp \
0 9.83190 temperature internal_timestamp 3.606766e+09
1 3.58847 conductivity internal_timestamp 3.606766e+09
2 22.96300 pressure internal_timestamp 3.606766e+09
3 32.89470 salinity internal_timestamp 3.606766e+09
stream_name
0 ctdpf_j_cspp_instrument
1 ctdpf_j_cspp_instrument
2 ctdpf_j_cspp_instrument
3 ctdpf_j_cspp_instrument
これが私が立ち往生しているところです。 value列とvalue_id列を取得し、value_idに基づいてこれらを新しい列にピボットします。
データフレームを次のようにしたいと思います。
stream_name preferred_timestamp internal_timestamp conductivity pressure salinity temperature
ctdpf_j_cspp_instrument internal_timestamp 3.606766e+09 3.58847 22.96300 32.89470 9.83190
ピボット関数とピボットテーブルPandas関数の両方を試し、「set_index」と「stack」を使用してテーブルを手動でピボットしようとしましたが、それは私が望む方法ではありません。
>>> df.pivot_table(values='value', index=['stream_name', 'preferred_timestamp', 'internal_timestamp', 'value_id'])
stream_name preferred_timestamp internal_timestamp value_id
ctdpf_j_cspp_instrument internal_timestamp 3.606766e+09 conductivity 3.58847
pressure 22.96300
salinity 32.89470
temperature 9.83190
Name: value, dtype: float64
これは近いですが、「value_id」の値を個別の列にピボットするようには見えませんでした。
そして
>>> df.pivot('stream_name', 'value_id', 'value')
value_id conductivity pressure salinity temperature
stream_name
ctdpf_j_cspp_instrument 3.58847 22.963 32.8947 9.8319
もう一度閉じますが、この行に関連付けたい他の列がありません。
私はここで立ち往生しています。これを行うエレガントな方法はありますか、それともDataFrameを分割して、希望どおりに再マージする必要がありますか?
最初の試みはほぼ正しかったので、インデックスに含める代わりにcolumns='value_id'
を使用してください。
# Perform the pivot.
df = df.pivot_table(
values='value',
index=['stream_name', 'preferred_timestamp', 'internal_timestamp'],
columns='value_id'
)
# Formatting.
df.reset_index(inplace=True)
df.columns.name = None
これはサンプルデータの問題ではありませんが、複数の値が同じ位置にピボットされた場合(デフォルトでは平均をとる)、pivot_table
が値を集約することに注意してください。