【问题标题】:Convert a dataframe column of dictionaries with lists into separate columns with pandas将带有列表的字典的数据框列转换为带有熊猫的单独列
【发布时间】:2021-10-24 06:51:29
【问题描述】:

我有一个数据框,其中一列作为列表,另一列作为字典。然而,这并不一致。它也可以是单个元素或 NULL。此外,它们被解析为字符串类型。数据框如下所示:

df = pd.DataFrame({'item_id':[1,2,3,4],
'shop_id':[['S1', 'S2', 'S3', 'S4'],'S2','S3',['S1', 'S2', 'S3', 'S4']], 
'price':[{'10':['S1','S2'], '20':['S3'], '30':['S4']},'50','NaN',{'10':['S1','S2','S3'],'25':['S4']}]})

+-------+---------+--------------------+----------------------------------------------------+
| Index | item_id |     shop_id        |                      price                         |
+-------+---------+--------------------+----------------------------------------------------+
|     0 |       1 | '[S1, S2, S3, S4]' | '{'10': ['S1', 'S2'], '20': ['S3'], '30': ['S4']}' |
|     1 |       2 | 'S2'               | '50'                                               |
|     2 |       3 | 'S3'               | 'NaN'                                              |
|     3 |       4 | '[S1, S2, S3, S4]' | '{'10': ['S1', 'S2', 'S3'], '25': ['S4']}'         |
+-------+---------+--------------------+----------------------------------------------------+

我希望将其扩展为:

+-------+---------+---------+-------+
| Index | item_id | shop_id | price |
+-------+---------+---------+-------+
|     0 |       1 | S1      | 10    |
|     1 |       1 | S2      | 10    |
|     2 |       1 | S3      | 20    |
|     3 |       1 | S4      | 30    |
|     4 |       2 | S2      | 50    |
|     5 |       3 | S3      | NaN   |
|     6 |       4 | S1      | 10    |
|     7 |       4 | S2      | 10    |
|     8 |       4 | S3      | 10    |
|     9 |       4 | S4      | 25    |
+-------+---------+---------+-------+

实现这一目标的最佳方法是什么?任何建议表示赞赏。谢谢!

【问题讨论】:

  • 我们是否保证字典中的 S 值不会映射到多个值?
  • @亨利·埃克。是的。这是有保证的:)

标签: python json pandas dataframe dictionary


【解决方案1】:

试试applyexplode

df['price'] = [[i for i in d.keys() for x in d[i]] if isinstance(d, dict) else [d] for d in df['price'].tolist()]
df = df.set_index('item_id').apply(pd.Series.explode, axis=0).reset_index()
print(df)

现在:

print(df)

愿意:

   item_id shop_id price
0        1      S1    10
1        1      S2    10
2        1      S3    20
3        1      S4    30
4        2      S2    50
5        3      S3   NaN
6        4      S1    10
7        4      S2    10
8        4      S3    10
9        4      S4    25

【讨论】:

  • 感谢您的回答!。这不能按预期工作,因为这些值被解析为字符串而不是字典。此外,还有单个条目是字符串或 NaN 并抛出 AttributeError: 'str' object has no attribute 'keys'。你能建议如何解决这个问题吗?
  • 评估部分不起作用,因为有些条目不是列表/字典。还需要考虑 NaN/NULL。同样的事情导致了关键问题
  • @charlie_boy 已编辑我的答案现在应该可以使用了
  • 很抱歉,像 '50' 这样的单个字符串条目会导致我之前提到的属性错误 - 'str' 对象没有属性 'keys'
  • @charlie_boy 这是一个错字,现在肯定可以工作
【解决方案2】:

您好,我有一个部分解决方案和一个问题。

我的代码是:

df1 = pd.DataFrame({ 
    "item_id" : [1, 2, 3, 4] , 
    "shop_id" : [['S1','S2','S3','S4'], "S2", "S3", ['S1','S2','S3','S4']],
    "price" : [{'10': ['S1', 'S2'], '20': ['S3'], '30': ['S4']}, 50, np.nan, {'10': ['S1', 'S2', 'S3'], '25': ['S4']}] })
df1 = df1.explode('shop_id')
df1 = df1.reset_index(drop=True)
item_id shop_id price
0 1 S1 {'10': ['S1', 'S2'], '20': ['S3'], '30': ['S4']}
1 1 S2 {'10': ['S1', 'S2'], '20': ['S3'], '30': ['S4']}
2 1 S3 {'10': ['S1', 'S2'], '20': ['S3'], '30': ['S4']}
3 1 S4 {'10': ['S1', 'S2'], '20': ['S3'], '30': ['S4']}
4 2 S2 50
5 3 S3 nan
6 4 S1 {'10': ['S1', 'S2', 'S3'], '25': ['S4']}
7 4 S2 {'10': ['S1', 'S2', 'S3'], '25': ['S4']}
8 4 S3 {'10': ['S1', 'S2', 'S3'], '25': ['S4']}
9 4 S4 {'10': ['S1', 'S2', 'S3'], '25': ['S4']}

对于价格列,您可以根据 shop_id 和 item_id 查找不同的表吗?如果没有,我可以继续尝试提出解决方案。

【讨论】:

  • 谢谢!爆炸肯定有帮助,但我想将数据框扩展为我提到的最终格式。这是我想解决的棘手部分。感谢您的帮助:)
猜你喜欢
  • 2021-09-07
  • 1970-01-01
  • 2016-09-06
  • 1970-01-01
  • 2021-04-13
  • 1970-01-01
  • 2017-12-12
  • 2018-11-25
  • 1970-01-01
相关资源
最近更新 更多