如何使用各种列表结构重塑 Python 字典

How do I reshape Python dictionary with various list structures

提问人:Srichard90 提问时间:11/10/2023 更新时间:11/10/2023 访问量:49

问:

我有来自字典的以下示例对象,我正在尝试展平数据,以便每个键值都将成为 pandas DataFrame 中自己的“列”。如您所见,这需要处理多个场景。我希望其中的每个 id 键在数据帧中成为它自己的列,然后将“value”键的相应值分配给该列。

我试图利用让我接近的 .json_normalize()(如果我排除 supplementalFieldValues,我会根据需要构建数据帧),但是我在同时将“supplementalFieldValues”列表中的键值转换为它们自己的字段时遇到了问题。或者也可以选择使用原始列表,而不使用 supplementalFieldValues,然后重塑 supplementalFieldValues,然后将其联接回原始列表。

    {
        "classification": [
            {
                "classificationId": "OperatingExpense",
                "taxonomyId": "accounting.gp"
            }
        ],
        "supplementalFieldValues": [
            {
                "id": "Account Class",
                "value": "Expense"
            },
            {
                "id": "Account Type",
                "value": "Expense"
            },
            {
                "id": "Account Subtype",
                "value": "PayrollExpenses"
            }
        ],
        "id": "182",
        "name": "Payroll - Admin",
        "userAssignedCode": "60100"
    },

我想要的输出如下所示:sample_output

Python Pandas 数据帧 字典

评论


答:

0赞 manucorujo 11/10/2023 #1

我认为以下步骤是一个可能的解决方案:

  1. 拼合词典以创建单级词典。
  2. 从拼合字典创建 DataFrame。

代码如下:

import pandas as pd

# Your sample data
data = {
    "classification": [
        {
            "classificationId": "OperatingExpense",
            "taxonomyId": "accounting.gp"
        }
    ],
    "supplementalFieldValues": [
        {
            "id": "Account Class",
            "value": "Expense"
        },
        {
            "id": "Account Type",
            "value": "Expense"
        },
        {
            "id": "Account Subtype",
            "value": "PayrollExpenses"
        }
    ],
    "id": "182",
    "name": "Payroll - Admin",
    "userAssignedCode": "60100"
}

# Function to flatten the dictionary
def flatten_dict(d, parent_key='', sep='_'):
    items = {}
    for key, value in d.items():
        new_key = f"{parent_key}{sep}{key}" if parent_key else key
        if isinstance(value, dict):
            items.update(flatten_dict(value, new_key, sep))
        else:
            items[new_key] = value
    return items

flattened_data = flatten_dict(data)

# Create a DataFrame from the flattened dictionary
df = pd.DataFrame([flattened_data])

# Display the DataFrame
print(df)

无论如何,您应该附加您正在使用的代码以查看哪些内容不起作用。

0赞 Srichard90 11/10/2023 #2

我的解决方案是在我的问题中遵循一个原始的想法。在 pandas 对象中,我从“supplementalFieldValues”中弹出项目并将它们存储到它们自己的列表中 (supp_list)。这使我更容易利用 defaultdict 包遍历此列表,同时利用就地 OR 运算符更新值以成为键。

res = defaultdict(dict)
for d in supp_list:
    res[d['i']] |= {'i': d['i'], d['id']: d.get('value')}

supplemental_list = [*res.values()]

现在我有了我的新supplemental_list,我只是将它连接到我的原始 pandas 对象 (flat_list) 中,该对象从中弹出了 supplementalFieldValues。

flat_data = flat_list.join(pd.DataFrame(supplemental_list).set_index('i')).reset_index(drop=True)