根据Python中的字符串结构动态创建列

问题描述 投票:0回答:1

为了提供项目背景,使用 python 中的 deepDiff 比较两个具有嵌套 JSON 结构的文档。在比较过程中,如果某个字段的值发生变化,这些值将被写入数据帧进行分析。

数据更改示例:

"values_changed": {
    "root['prod1']['p_col']['c_col']": {
        "new_value": -2.866711109999983,
        "old_value": -2.75
    },
    "root['prod1']['p_col23']": {
        "new_value": 1,
        "old_value": 54
    },
    "root['prod1']['p_col']['c_col2']['c_col5']": {
        "new_value": 1.678,
        "old_value": 5.12
    }
}

电流输出:

产品 新值 旧值
产品 p_col -2.866 -2.75
产品 p_col23 1 54
产品 p_col 1.678 5.12

我正在使用字符串模式读取直到root['prod1']['p_col'],添加到另一个字典进一步转换为pandas数据帧

k = """root['prod1']['p_col']['c_col']"""
field = k[k.find("['",8)+1:k.find("']",-1)].split("'")[1::2][0]

但想要在字符串中存在嵌套字段时动态添加新列

所需输出:

产品 父字段 新值 旧值
产品 p_col c_col -2.866 -2.75
产品 p_col23 1 54
产品 p_col c_col2 c_col5 1.678 5.12
python pandas string dictionary dynamic-programming
1个回答
0
投票

因此,实现此目的的一种方法如下,但只有当您

json
具有您提供的结构时,我提供的解决方案才有效。如果不同,您需要将其调整为新的布局:

import pandas as pd

values_changed = {
    "root['prod1']['p_col']['c_col']": {
        "new_value": -2.866711109999983,
        "old_value": -2.75
    },
    "root['prod1']['p_col23']": {
        "new_value": 1,
        "old_value": 54
    },
    "root['prod1']['p_col']['c_col2']['c_col5']": {
        "new_value": 1.678,
        "old_value": 5.12
    }
}

def process_change(key, change):
    parts = [part for part in key.split("']['") if part]
    
    parts[0] = parts[0].replace("root['", "")
    parts[-1] = parts[-1].replace("']", "")
    
    new_value = change['new_value']
    old_value = change['old_value']
    
    return parts, new_value, old_value

max_depth = 0
processed_changes = []
for key, change in values_changed.items():
    parts, new_value, old_value = process_change(key, change)
    max_depth = max(max_depth, len(parts))
    processed_changes.append((parts, new_value, old_value))

rows = []
for parts, new_value, old_value in processed_changes:
    field_parts = parts[1:] + [''] * (max_depth - len(parts))
    row = [parts[0]] + field_parts + [new_value, old_value]
    rows.append(row)

column_names = ['product'] + [f'field_{i}' for i in range(1, max_depth)] + ['new_value', 'old_value']

df = pd.DataFrame(rows, columns=column_names)
df = df.rename(columns={'field_1': 'parent-field', 'field_2': 'child-field', 'field_3': 'grandchild-field})
print(df)

这会给你

  product parent-field child-field grandchild-field  new_value  old_value
0   prod1        p_col       c_col                   -2.866711      -2.75
1   prod1      p_col23                                1.000000      54.00
2   prod1        p_col      c_col2           c_col5   1.678000       5.12
© www.soinside.com 2019 - 2024. All rights reserved.