【问题标题】:Python pandas extract values from dict within a listPython pandas 从列表中的 dict 提取值
【发布时间】:2016-02-26 14:53:52
【问题描述】:

基本上我想从该列中提取价格值,但是如果我使用索引 [0] 会在第 11 行带来索引 [0] 错误,并且价格键也不会在该行中退出。

p>
ex
0    {u'availableToBack': [{u 'price' : 1.02, u 'size' : 2.15}], u 'availableToLay' : [], u 'tradedVolume' : []}
1    {u'availableToBack': [{u'price': 6.8, u'size':...
2    {u'availableToBack': [{u'price': 8.2, u'size':...
3    {u'availableToBack': [{u'price': 9.6, u'size':...
10   {u'availableToBack': [{u'price': 70.0, u'size'...
11   {u'availableToBack': [], u'availableToLay': []...
12   {u'availableToBack': [], u'availableToLay': []...

我用这样的东西

table['price'] = table['ex']['availableToBack'][0].apply(lambda x: x.get('price'))

你能帮我解决一下吗?

JSON 看起来像这样:

    u 'runners' : [{
            u 'status' : u 'ACTIVE',
            u 'handicap' : 0.0,
            u 'selectionId' : 10861647,
            u 'totalMatched' : 0.0,
            u 'adjustmentFactor' : 16.631,
            u 'ex' : {
                u 'availableToBack' : [{
                        u 'price' : 1.02,
                        u 'size' : 2.15
                    }
                ],
                u 'availableToLay' : [],
                u 'tradedVolume' : []
            }
        }, {
            u 'status' : u 'ACTIVE',
            u 'handicap' : 0.0,
            u 'selectionId' : 10861648,
            u 'totalMatched' : 0.0,
            u 'adjustmentFactor' : 13.237,
            u 'ex' : {
                u 'availableToBack' : [{
                        u 'price' : 1.01,
                        u 'size' : 7.11
                    }
                ],
                u 'availableToLay' : [],
                u 'tradedVolume' : []
            }
        },

【问题讨论】:

  • 你能发布你的 json 吗?我在 0 之后没有看到 :

标签: python python-2.7 python-3.x pandas


【解决方案1】:
10   {u'availableToBack': [{u'price': 70.0, u'size'...
11   {u'availableToBack': [], u'availableToLay': []...

我刚刚看到您的 availableToBack 条目包含一个空列表。如果列表值为空,则进行测试,将其设置为 [dict()]。这将允许x.get('price', 0) 正常工作。然后,您将能够在其余代码中将“价格”的值处理为 0。

您将不必测试“无”。

x.get('price') 没有指定“默认”值,因此它返回“无”。设置一个默认值(如x.get('price', 0))这样你应该可以以0价格执行操作。

Python dictionary get() Method

说明

get() 方法返回给定键的值。如果键不是 可用然后返回默认值无。语法

以下是 get() 方法的语法 -

dict.get(key, default=None)

参数

key -- This is the Key to be searched in the dictionary.

default -- This is the Value to be returned in case key does not exist.

返回值

此方法返回给定键的值。如果密钥不可用, 然后它返回默认值 None。

【讨论】:

    【解决方案2】:

    我认为 Python 没有一种安全的内置方法,可以在不触发 IndexError 的情况下从列表中获取值,但编写它很容易。 (This answer 对此有更详细的说明。)

    如果我正确理解您的意图,这可能会对您有所帮助。 (请注意,这只解决了安全获取列表项的问题。您可能希望对要检索的每个字典值使用 .get 以提高安全性。)

    def safeget(seq, index, default=None):
        try:
            return seq[index]
        except IndexError:
            return default
    
    for table in runners:
        price = safeget(table['ex']['availableToBack'], 0, default={}).get('price')
        print price
    

    我针对这个结构进行了测试,它在第二个对象中有一个空列表 u'availableToBack

    runners = [
        {
            u'status' : u'ACTIVE',
            u'handicap' : 0.0,
            u'selectionId' : 10861647,
            u'totalMatched' : 0.0,
            u'adjustmentFactor' : 16.631,
            u'ex' : {
                u'availableToBack' : [
                        {u'price' : 1.02, u'size' : 2.15},
                    ],
                u'availableToLay' : [],
                u'tradedVolume' : []
                }
        }, {
            u'status' : u'ACTIVE',
            u'handicap' : 0.0,
            u'selectionId' : 10861648,
            u'totalMatched' : 0.0,
            u'adjustmentFactor' : 13.237,
            u'ex' : {
                u'availableToBack' : [
                    ## this one is MISSING a price
                ],
                u'availableToLay' : [],
                u'tradedVolume' : []
            }
        }
    ]
    

    【讨论】:

    • 我认为他使用的是 dict() 类型,键为 'price' 我认为问题在于没有默认值,它返回的值为 None。
    • 我认为问题在于他的availableToBack 是一个有时可能为空的数组,所以他的[0] 索引有时会引发IndexError。 (他的第一个示例的第 11 行有一个空数组。)
    【解决方案3】:

    您可以使用三元运算符。空列表的计算结果为 false。

    table['price'] = (table['ex']['availableToBack'][0].get('price') 
                      if table['ex']['availableToBack'] 
                      else None)
    

    【讨论】:

      【解决方案4】:

      我找到了解决方案并决定发布它。基本上也许我没有解释清楚,但问题是列表中的任何内容不一致。

      table['availableToBack.price'] = table['ex'].apply(lambda x: x['availableToBack'][0].get('price') if (len(x['availableToBack']) != 0) else None) 
      

      【讨论】:

      • 你也可以做一个列表理解而不是 apply/lambda.[xx['availableToBack'][0].get('price') for xx in table['ex'] if len(xx['availableToBack']) else None]
      猜你喜欢
      • 1970-01-01
      • 2018-10-12
      • 2021-09-03
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-25
      相关资源
      最近更新 更多