リストをネストしたデータフレームへのインポートを処理する必要があるJSONファイルは、データフレームに変換する前に、ネストされたdictのリストです。ファイル自体はネストされています。
サンプルJSON:
{
"State": [
{
"ts": "2018-04-11T21:37:05.401Z",
"sensor": [
"accBodyX_ftPerSec2"
],
"value": null
},
{
"ts": "2018-04-11T21:37:05.901Z",
"sensor": [
"accBodyX_ftPerSec2"
],
"value": [
-3.38919
]
},
{
"ts": "2018-04-11T21:37:05.901Z",
"sensor": [
"accBodyY_ftPerSec2"
],
"value": [
-2.004781
]
},
{
"ts": "2018-04-11T21:37:05.901Z",
"sensor": [
"accBodyZ_ftPerSec2"
],
"value": [
-34.77694
]
}
]
}
データフレームは次のようになります。
sensor ts value
0 [accBodyX_ftPerSec2] 2018-04-11T21:37:05.901Z [-3.38919]
1 [accBodyY_ftPerSec2] 2018-04-11T21:37:05.901Z [-2.004781]
2 [accBodyZ_ftPerSec2] 2018-04-11T21:37:05.901Z [-34.77694]
最終的には、ネストを削除するか、ネストを操作する方法を見つけてください。目標は、タイムスタンプを伴う特定のセンサー名の値のリストを、次のような処理/プロットのために別のデータフレームに抽出することです。
ts value
0 2018-04-11T21:37:05.901Z -3.38919
1 2018-04-11T21:37:06.401Z -3.00241
2 2018-04-11T21:37:06.901Z -3.87694
ネストを削除するためにこれを実行しましたが、100,000行だけでは低速ですが、ありがたいことにforループよりもはるかに高速です。(この投稿のおかげで、列に対するpython pandas操作が可能になりました)
def func(row):
row.sensor = row.sensor[0]
if type(row.value) is list:
row.value = row.value[0]
return row
df.apply(func, axis=1)
ネストを操作するために、個々の値を抽出できます。例:これ:
print( df.iloc[:,2].iloc[1][0] )
-2.004781
ただし、各行内の各リストのインデックス0から値のリストを返そうとすると、最初の値だけが返されます。
print( df.iloc[:,2].iloc[:][0] )
-3.38919
もちろん、これはforループで実行できますが、まだ発見できないPandas関数で実行する方法があることはわかっています。
DataFrameに読み込む前に、手動でクリーンアップする必要がある場合があります。
>>> import json
>>> import pandas as pd
>>> def collapse_lists(data):
... return [{k: v[0] if (isinstance(v, list) and len(v) == 1)
... else v for k, v in d.items()} for d in data]
>>> with open('state.json') as f:
... data = pd.DataFrame(collapse_lists(json.load(f)['State']))
>>> data
sensor ts value
0 accBodyX_ftPerSec2 2018-04-11T21:37:05.401Z NaN
1 accBodyX_ftPerSec2 2018-04-11T21:37:05.901Z -3.389190
2 accBodyY_ftPerSec2 2018-04-11T21:37:05.901Z -2.004781
3 accBodyZ_ftPerSec2 2018-04-11T21:37:05.901Z -34.776940
これにより、JSONファイルがPythonの辞書リストに読み込まれ、長さ1のリストがスカラー値に変換されてから、その結果がDataFrameに読み込まれます。これは確かに最も効率的な手段ではありませんが、ファイルが大量でない限り、JSON自体を解析する他のオプションはおそらくやり過ぎです。
最後に、日時に変換するには:
>>> data['ts'] = pd.to_datetime(data['ts'])
>>> data.dtypes
sensor object
ts datetime64[ns]
value float64
dtype: object
sensor
おそらくかなりの量のメモリを節約するために、カテゴリデータ型への変換を検討することもできます。
カテゴリカルのメモリ使用量は、カテゴリの数とデータの長さに比例します。対照的に、オブジェクトのdtypeは、データの長さの定数倍です。(ソース)
明示的なループ形式では、これは次のようになります。
def collapse_lists(data):
result = []
for d in data:
entry = {}
for k, v in d.items():
if isinstance(k, list) and len(v) == 1:
entry.update({k: v[0]})
else:
entry.update({k: v})
result.append(entry)
return result
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加