如何将 Pandas 系列中的多个字典键转换为 DataFrame 中的列?

How to convert multiple dictionary keys in a Pandas Series to columns in a DataFrame?

我有以下 pandas 包含 2 列的 DataFrame:地址和交易。

    Address                                     Transactions
0   0x88aDa02f6fCE2F1A835567B4999D62a7ebb70367  [{'type': 'outflow', 'amount': '250,000 VSO'}, {'type': inflow, 'amount': 100,000}]
1   0x00979Bd14bD5Eb5c424c5478d3BF4b6E9212bA7d  [{'type': 'inflow', 'amount': '9.1283802424254'}, {'type': inflow, 'amount': 100,000}]
2   0x5852346d9dC3d64d81dc82fdddd5Cc1211157cD5  [{'type': 'outflow', 'amount': '7,200 VSO'}, {'type': inflow, 'amount': 100,000}]

每个地址都有多个交易,一个地址的所有交易都由一个列表表示,每个交易包含一个字典。

每个字典都有两个键和两个值:分别是类型和数量。

创建上述 table 的代码如下:

df_dict = pd.DataFrame(dict_all_txs_all_addresses.items(), columns=['Address', 'Transactions'])

我想做的事情:
我想创建一个多索引(可能是不必要的?)table,看起来有点像这样:

    Address                                         Type                             Amount
    0   0x88aDa02f6fCE2F1A835567B4999D62a7ebb70367  outflow                          250,000 VSO
                                                    inflow                           100,000 VSO

    1   0x00979Bd14bD5Eb5c424c5478d3BF4b6E9212bA7d  inflow                           330,000 VSO
                                                    inflow                           150,000 VSO'

它在不同的行中显示每笔交易,同时只维护一个地址。请注意,此模型 table 有 3 列。

也许这可以使用 df.groupby() 而不是多索引 df 来解决?

为了便于阅读和操作,这里有一个字典示例:

dict_all_txs_all_addresses = {
        "0x00979Bd14bD5Eb5c424c5478d3BF4b6E9212bA7d": [
            {
                "amount": "330,000 VSO",
                "type": "inflow"
            },
            {
                "amount": "150,000 VSO",
                "type": "inflow"
            }
        ],
        "0x88aDa02f6fCE2F1A833cd9B4999D62a7ebb70367": [
            {
                "amount": "250,000 VSO",
                "type": "outflow"
            },
            {
                "amount": "100,000 VSO",
                "type": "inflow"
            }
        ]
    }

展开 Transactions 列,然后使用 apply(pd.Series) 技巧将其展开成多列:

(df.set_index('Address')
   .explode('Transactions')
   .Transactions
   .apply(pd.Series)
   .set_index('type', append=True))

                                                         amount
Address                                    type                
0x00979Bd14bD5Eb5c424c5478d3BF4b6E9212bA7d inflow   330,000 VSO
                                           inflow   150,000 VSO
0x88aDa02f6fCE2F1A833cd9B4999D62a7ebb70367 outflow  250,000 VSO
                                           inflow   100,000 VSO

如果您需要所有列作为普通列而不是索引,请使用 reset_index 而不是 set_index:

df.set_index('Address').explode('Transactions').Transactions.apply(pd.Series).reset_index()

                                      Address       amount     type
0  0x00979Bd14bD5Eb5c424c5478d3BF4b6E9212bA7d  330,000 VSO   inflow
1  0x00979Bd14bD5Eb5c424c5478d3BF4b6E9212bA7d  150,000 VSO   inflow
2  0x88aDa02f6fCE2F1A833cd9B4999D62a7ebb70367  250,000 VSO  outflow
3  0x88aDa02f6fCE2F1A833cd9B4999D62a7ebb70367  100,000 VSO   inflow

我们可以在这里使用pd.json_normalize来得到一个可用的整洁格式:

df = df.explode("Transactions", ignore_index=True)
df = pd.concat([df, pd.json_normalize(df.pop("Transactions"))], axis=1)
                                      Address       amount     type
0  0x00979Bd14bD5Eb5c424c5478d3BF4b6E9212bA7d  330,000 VSO   inflow
1  0x00979Bd14bD5Eb5c424c5478d3BF4b6E9212bA7d  150,000 VSO   inflow
2  0x88aDa02f6fCE2F1A833cd9B4999D62a7ebb70367  250,000 VSO  outflow
3  0x88aDa02f6fCE2F1A833cd9B4999D62a7ebb70367  100,000 VSO   inflow