JSONをCSVファイルに変換しようとしています。これをさらに分析するために使用できます。私の構造の問題は、JSONファイルを変換するときにかなりのネストされたdict /リストがあることです。
私はpandas json_normalize()
_を使おうとしましたが、最初のレベルのみがフラットになります。
import json
import pandas as pd
from pandas.io.json import json_normalize
from cs import CloudStack
api_key = xxxx
secret = xxxx
endpoint = xxxx
cs = CloudStack(endpoint=endpoint,
key=api_key,
secret=secret)
virtual_machines = cs.virtMach()
test = json_normalize(virtual_machines["virtualmachine"])
test.to_csv("test.csv", sep="|", index=False)
JSONファイル全体をフラット化する方法はありますか?単一(この場合は仮想マシン)エントリのCSVファイルへの単一行入力を作成できますか?私はここに投稿されたいくつかの解決策を試しましたが、私の結果は常に最初のレベルだけが平坦化されていました。
これはサンプルのJSONです(この場合も、「securitygroup」と「nic」の出力がJSON形式で表示されます。
{
"count": 13,
"virtualmachine": [
{
"id": "1082e2ed-ff66-40b1-a41b-26061afd4a0b",
"name": "test-2",
"displayname": "test-2",
"securitygroup": [
{
"id": "9e649fbc-3e64-4395-9629-5e1215b34e58",
"name": "test",
"tags": []
}
],
"nic": [
{
"id": "79568b14-b377-4d4f-b024-87dc22492b8e",
"networkid": "05c0e278-7ab4-4a6d-aa9c-3158620b6471"
},
{
"id": "3d7f2818-1f19-46e7-aa98-956526c5b1ad",
"networkid": "b4648cfd-0795-43fc-9e50-6ee9ddefc5bd"
"traffictype": "Guest"
}
],
"hypervisor": "KVM",
"affinitygroup": [],
"isdynamicallyscalable": false
}
]
}
よろしくお願いいたします。Bostjan
他の誰かがここで自分を見つけ、その後のプログラムによる処理により適したソリューションを探している場合:
リストをフラット化すると、リストの長さなどの見出しを処理する必要が生じます。たとえば、2つのリストがある場合、 2つの要素があると、4つの行が生成され、有効な各データ行が生成されます(実際の例については以下を参照してください)。
class MapFlattener:
def __init__(self):
self.headings = []
self.rows = []
def add_rows(self, headings, rows):
self.headings = [*self.headings, *headings]
if self.rows:
new_rows = []
for base_row in self.rows:
for row in rows:
new_rows.append([*base_row, *row])
self.rows = new_rows
else:
self.rows = rows
def __call__(self, mapping):
for heading, value in mapping.items():
if isinstance(value, Mapping):
sub_headings, sub_rows = MapFlattener()(value)
sub_headings = [f'{heading}:{sub_heading}' for sub_heading in sub_headings]
self.add_rows(sub_headings, sub_rows)
continue
if isinstance(value, list):
self.add_rows([heading], [[e] for e in value])
continue
self.add_rows([heading], [[value]])
return self.headings, self.rows
def map_flatten(mapping):
return MapFlattener()(mapping)
これにより、リレーショナルデータに沿った出力が作成されます。
In [22]: map_flatten({'l': [1,2]})
Out[22]: (['l'], [[1], [2]])
In [23]: map_flatten({'l': [1,2], 'n': 7})
Out[23]: (['l', 'n'], [[1, 7], [2, 7]])
In [24]: map_flatten({'l': [1,2], 'n': 7, 'o': {'a': 1, 'b': 2}})
Out[24]: (['l', 'n', 'o:a', 'o:b'], [[1, 7, 1, 2], [2, 7, 1, 2]])
これは、スプレッドシートなどでcsvを使用していて、フラット化されたデータを処理する必要がある場合に特に便利です。