【问题标题】:How to convert nested json to csv with multiple different names?如何将嵌套的 json 转换为具有多个不同名称的 csv?
【发布时间】:2022-08-16 21:28:57
【问题描述】:

我一直在尝试将嵌套的 json 文件转换为 csv。这是 json 文件的一个小例子。

 json_data =   
{\"labels\":
    {
      \"longfilename01:png\": {
        \"events\": {
          \"-N8V6uUR__vvB0qv1lPb\": {
            \"t\": \"2022-08-02T19:54:23.608Z\",
            \"user\": \"bmEhwNCZT9Wiftgvsopb7vBjO9o1\"
          }
        },
        \"questions\": {
          \"would-you\": {
            \"-N8V6uUR__vvB0qv1lPb\": {
              \"answer\": \"no\",
              \"format\": 1
            }
          }
        }
      },
      \"longfilename02:png\": {
        \"events\": {
          \"-N8ILnaH-1ylwp2LGvtP\": {
            \"t\": \"2022-07-31T08:24:23.698Z\",
            \"user\": \"Qf7C5cXQkXfQanxKPR0rsKW4QzE2\"
          }
        },
        \"questions\": {
          \"would-you\": {
            \"-N8ILnaH-1ylwp2LGvtP\": {
              \"answer\": \"yes\",
              \"format\": 1
            }
          }
        }
      }

我尝试了多种方法来获得此输出:

Labels Event User Time Answer
Long filename 01 -N8V6uUR__vvB0qv1lPb bmEhwNCZT9Wiftgvsopb7vBjO9o1 2022-08-02T19:54:23.608Z no
Long filename 02 -N8ILnaH-1ylwp2LGvtP bmEhwNCZT9Wiftgvsopb7vBjO9o1 2022-07-31T08:24:23.698Z yes

如果我正常化:

f= open(\'after_labels.json\')

data = json.load(f)

df = pd.json_normalize(data)

或者尝试使用多种功能来展平文件,例如:

def flatten_json(json):
    def process_value(keys, value, flattened):
        if isinstance(value, dict):
            for key in value.keys():
                process_value(keys + [key], value[key], flattened)
        elif isinstance(value, list):
            for idx, v in enumerate(value):
                process_value(keys + [str(idx)], v, flattened)
        else:
            flattened[\'__\'.join(keys)] = value

    flattened = {}
    for key in json.keys():
        process_value([key], json[key], flattened)
    return flattened

df = flatten_json(data)

或者

from copy import deepcopy
import pandas


def cross_join(left, right):
    new_rows = [] if right else left
    for left_row in left:
        for right_row in right:
            temp_row = deepcopy(left_row)
            for key, value in right_row.items():
                temp_row[key] = value
            new_rows.append(deepcopy(temp_row))
    return new_rows


def flatten_list(data):
    for elem in data:
        if isinstance(elem, list):
            yield from flatten_list(elem)
        else:
            yield elem


def json_to_dataframe(data_in):
    def flatten_json(data, prev_heading=\'\'):
        if isinstance(data, dict):
            rows = [{}]
            for key, value in data.items():
                rows = cross_join(rows, flatten_json(value, prev_heading + \'.\' + key))
        elif isinstance(data, list):
            rows = []
            for item in data:
                [rows.append(elem) for elem in flatten_list(flatten_json(item, prev_heading))]
        else:
            rows = [{prev_heading[1:]: data}]
        return rows

    return pandas.DataFrame(flatten_json(data_in))

df = json_to_dataframe(data)
print(df)

它给了我 292 列,我怀疑这是因为长的唯一文件名。

我不能在处理之前更改 json 文件,因为这似乎是做 \"filename\": \"longfilename01:png\" 的简单解决方案,因为它们都是一致的,我不会有这个问题.

对于如何解决这个问题的任何其他聪明的想法,我将不胜感激。

    标签: python json csv nested


    【解决方案1】:

    尝试:

    json_data = {
        "labels": {
            "longfilename01:png": {
                "events": {
                    "-N8V6uUR__vvB0qv1lPb": {
                        "t": "2022-08-02T19:54:23.608Z",
                        "user": "bmEhwNCZT9Wiftgvsopb7vBjO9o1",
                    }
                },
                "questions": {
                    "would-you": {
                        "-N8V6uUR__vvB0qv1lPb": {"answer": "no", "format": 1}
                    }
                },
            },
            "longfilename02:png": {
                "events": {
                    "-N8ILnaH-1ylwp2LGvtP": {
                        "t": "2022-07-31T08:24:23.698Z",
                        "user": "Qf7C5cXQkXfQanxKPR0rsKW4QzE2",
                    }
                },
                "questions": {
                    "would-you": {
                        "-N8ILnaH-1ylwp2LGvtP": {"answer": "yes", "format": 1}
                    }
                },
            },
        }
    }
    
    
    df = pd.DataFrame(
        [
            {
                "Labels": k,
                "Event": list(v["events"])[0],
                "User": list(v["events"].values())[0]["user"],
                "Time": list(v["events"].values())[0]["t"],
                "Answer": list(list(v["questions"].values())[0].values())[0][
                    "answer"
                ],
            }
            for k, v in json_data["labels"].items()
        ]
    )
    print(df)
    

    印刷:

                   Labels                 Event                          User                      Time Answer
    0  longfilename01:png  -N8V6uUR__vvB0qv1lPb  bmEhwNCZT9Wiftgvsopb7vBjO9o1  2022-08-02T19:54:23.608Z     no
    1  longfilename02:png  -N8ILnaH-1ylwp2LGvtP  Qf7C5cXQkXfQanxKPR0rsKW4QzE2  2022-07-31T08:24:23.698Z    yes
    

    【讨论】:

      猜你喜欢
      • 2020-02-19
      • 2021-10-21
      • 2018-01-07
      • 2020-10-28
      • 2020-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-10-27
      相关资源
      最近更新 更多