python - Convertir csv en estructura de árbol JSON?
d3.js tree (1)
El uso de default de la biblioteca estándar de colecciones genera muchos problemas con estructuras jerárquicas fáciles y solucionables. Así que he desarrollado una solución de muestra para su problema. Pero antes de ejecutar el script, por favor, asegúrese de tener un archivo csv separado por comas (llamado test.csv) o puede cambiar la lógica del lector csv allí.
Aquí está el archivo csv en el que he probado el script.
condition, target, sub, dub
oxygen,tree,G1,T1
oxygen,tree,G2,T1
oxygen,tree,G2,T2
water,car,G3,T1
water,tree,GZ,T1
water,tree,GZ,T2
fire,car,GTD,T3
oxygen,bomb,GYYS,T1
Técnicamente, la secuencia de comandos debería funcionar para cualquier tipo de archivo csv, con varias dimensiones. Pero debe probarlo usted mismo para estar seguro.
import csv
from collections import defaultdict
def ctree():
""" One of the python gems. Making possible to have dynamic tree structure.
"""
return defaultdict(ctree)
def build_leaf(name, leaf):
""" Recursive function to build desired custom tree structure
"""
res = {"name": name}
# add children node if the leaf actually has any children
if len(leaf.keys()) > 0:
res["children"] = [build_leaf(k, v) for k, v in leaf.items()]
return res
def main():
""" The main thread composed from two parts.
First it''s parsing the csv file and builds a tree hierarchy from it.
Second it''s recursively iterating over the tree and building custom
json-like structure (via dict).
And the last part is just printing the result.
"""
tree = ctree()
# NOTE: you need to have test.csv file as neighbor to this file
with open(''test.csv'') as csvfile:
reader = csv.reader(csvfile)
for rid, row in enumerate(reader):
# skipping first header row. remove this logic if your csv is
# headerless
if rid == 0:
continue
# usage of python magic to construct dynamic tree structure and
# basically grouping csv values under their parents
leaf = tree[row[0]]
for cid in range(1, len(row)):
leaf = leaf[row[cid]]
# building a custom tree structure
res = []
for name, leaf in tree.items():
res.append(build_leaf(name, leaf))
# printing results into the terminal
import json
print(json.dumps(res))
# so let''s roll
main()
Y aquí está el segmento json del resultado:
{
"name": "oxygen",
"children": [
{
"name": "tree",
"children": [
{
"name": "G2",
"children": [
{
"name": "T2"
},
{
"name": "T1"
}
]
},
{
"name": "G1",
"children": [
{
"name": "T1"
}
]
}
]
},
{
"name": "bomb",
"children": [
{
"name": "GYYS",
"children": [
{
"name": "T1"
}
]
}
]
}
]
}
Por favor, avíseme si tiene más preguntas y problemas. Pitonimia feliz;)
Leí estas preguntas:
- datos de csv al árbol json anidado en d3
- Crear un árbol json de la lista csv en python
- Cómo crear un árbol JSON desde una jerarquía tabulada en Python
- Python csv a JSON anidado [cerrado]
Sin embargo, todavía no puedo convertir un archivo csv a una jerarquía para JSON. Todos los scripts que encontré en stackoverflow son específicos para cierto problema. Digamos que hay tres variables que deben agruparse:
condition target sub
oxygen tree G1
oxygen tree G2
water car G3
water tree GZ
fire car GTD
oxygen bomb GYYS
Esto dará como resultado un archivo JSON como este (por lo que he intentado):
oxygen
- tree
- G1
- G2
- bomb
-GYYS
water
- car
- G3
- tree
-GZ
fire
- car
- GTD
Y estos tienen que estar agrupados en una estructura anidada como:
{
"name": "oxygen",
"children": [
{
"name": "tree",
"children": [
{"name": "G1"},
{"name": "G2"},
{"name": "GYYS"}
]
},
{
"name": "bomb",
"children": [
{"name": "GYYS"}
]
}
]
}
etc.
Intenté cada script en este sitio, pero no puedo hacer una función genérica que pueda hacer un flare.json así. Puedo publicar mi código, pero esto es como los enlaces provistos arriba. Así que estoy pidiendo un código simple (o un ejemplo que pueda ayudarme) para convertir esto en una estructura flare.JSON like.