【问题标题】:Convert list of dictionaries containing another list of dictionaries to dataframe将包含另一个字典列表的字典列表转换为数据框
【发布时间】:2018-10-10 21:48:44
【问题描述】:

我试图寻找解决方案,但我无法得到 1。我从 python 中的 api 得到以下输出。

insights = [ <Insights> {
    "account_id": "1234",
    "actions": [
        {
            "action_type": "add_to_cart",
            "value": "8"
        },
        {
            "action_type": "purchase",
            "value": "2"
        }
    ],
    "cust_id": "xyz123",
    "cust_name": "xyz",
}, <Insights> {
    "account_id": "1234",
    "cust_id": "pqr123",
    "cust_name": "pqr",
},  <Insights> {
    "account_id": "1234",
    "actions": [
        {
            "action_type": "purchase",
            "value": "45"
        }
    ],
    "cust_id": "abc123",
    "cust_name": "abc",
 }
 ]

我想要这样的数据框

- account_id    add_to_cart purchase    cust_id cust_name
- 1234                    8        2    xyz123  xyz
- 1234                                  pqr123  pqr
- 1234                            45    abc123  abc

当我使用下面的

> insights_1 = [x for x in insights]

> df = pd.DataFrame(insights_1)

我得到以下内容

- account_id                                       actions  cust_id cust_name
- 1234  [{'value': '8', 'action_type': 'add_to_cart'},{'value': '2', 'action_type': 'purchase'}]                                    xyz123  xyz
- 1234                                              NaN     pqr123  pqr
- 1234  [{'value': '45', 'action_type': 'purchase'}]        abc123  abc

我该如何继续?

【问题讨论】:

  • 很抱歉问这个问题,&lt;insights&gt; 是什么?
  • 调用API时输出是这样显示的。

标签: python pandas dictionary dataframe


【解决方案1】:

这是一种解决方案。

df = pd.DataFrame(insights)

parts = [pd.DataFrame({d['action_type']: d['value'] for d in x}, index=[0])
         if x == x else pd.DataFrame({'add_to_cart': [np.nan], 'purchase': [np.nan]})
         for x in df['actions']]

df = df.drop('actions', 1)\
       .join(pd.concat(parts, axis=0, ignore_index=True))

print(df)

  account_id cust_id cust_name add_to_cart purchase
0       1234  xyz123       xyz           8        2
1       1234  pqr123       pqr         NaN      NaN
2       1234  abc123       abc         NaN       45

说明

  • 利用pandas 将外部字典列表读入数据帧。
  • 对于内部字典,将列表推导与字典推导一起使用。
  • 通过测试列表理解中的相等性来计算 nan 值。
  • 将各部分连接并连接到原始数据帧。

解释 - 细节

这里详述parts的构造和使用:

  1. 获取df['actions']中的每个条目;每个条目将是一个 列表 字典
  2. for 循环中逐一(即逐行)迭代它们。
  3. else 部分表示“如果是 np.nan [即 null],则返回 nans 的数据帧”。 if 部分获取字典列表并为每一行创建一个迷你数据框
  4. 然后我们使用下一部分连接这些迷你字典,每行一个,并将它们连接到原始数据帧。

【讨论】:

  • 您的解决方案工作得非常好,直到我被要求添加一个参数。我已经用详细信息编辑了原始问题。你能帮我解决这个问题吗?
  • @raul0002,我已经回滚了你的问题。您能否将问题作为一个单独的问题发布并链接到这个问题?您的编辑不会丢失(您仍然可以在修订版中访问它)。但鉴于其他人已经发布了答案,重要的是我们没有单独的问答。
  • 上述问题的扩展链接是stackoverflow.com/questions/50119490/…
【解决方案2】:

我认为将apply 用于您的df 将是一种选择。首先我会用空列表替换NaN

df['actions'][df['actions'].isnull()] = df['actions'][df['actions'].isnull()].apply(lambda x: [])

如果类型为add_to_cart,则创建一个函数add_to_cart 来读取操作列表,并使用apply 创建列:

def add_to_cart(list_action):
    for action in list_action:
        # for each action, see if the key action_type has the value add_to_cart and return the value
        if action['action_type'] == 'add_to_cart':
            return action['value']
    # if no add_to_cart action, then empty
    return ''

df['add_to_cart'] = df['actions'].apply(add_to_cart)

purchase 的想法相同:

def purchase(list_action):
    for action in list_action:
        if action['action_type'] == 'purchase':
            return action['value']
    return ''

df['purchase'] = df['actions'].apply(purchase)

然后您可以根据需要删除列actions

df = df.drop('actions',axis=1)

编辑:定义一个独特的函数find_action 然后apply 带有一个参数,例如:

def find_action(list_action, action_type):
    for action in list_action:
        # for each action, see if the key action_type is the one wanted
        if action['action_type'] == action_type:
            return action['value']
    # if not the right action type found, then empty
    return ''
df['add_to_cart'] = df['actions'].apply(find_action, args=(['add_to_cart']))
df['purchase'] = df['actions'].apply(find_action, args=(['purchase']))

【讨论】:

    猜你喜欢
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多