【问题标题】:Evaluate a string to a dictionary when there are null values in the dictionary当字典中有空值时,将字符串评估为字典
【发布时间】:2020-01-04 00:15:30
【问题描述】:

我有一个看起来像这样的数据框(Thing_2 被评估为一个字符串):

ID           Thing           Thing_2
1             abc            [{"object_1": "a", "object_2": null}]
2             def            None

我希望它看起来像这样:

ID           Thing           Thing_2
1             abc            a
2             def            None

为此,我执行了以下步骤:

def change_to_dict(row):
     t2 = row['Thing_2']
     if pd.notna(row['Thing_2']):
          t2 = t2.strip('[]') 
          t2 = ast.literal_eval(t2)
          return t2.get[0]

我不断收到 value_error: malformed node 在它不为空的索引处。我认为这是因为字典中有一个空值作为第二个值。

【问题讨论】:

  • @Priya,您的 DataFrame 是否看起来像在 Thing_2 列中,它有 2 个键和两个值,您只需要从列中提取第一个值吗?
  • @rafaelc 由于机密性,我无法发布确切的内容,但该列 dict 看起来像这样 'Thing_2': {0: None, 1: None, 2: '{"object_1": "a", "object_2": null}'}
  • @pygo 是的,它是
  • 而不是 ast.literal_eval 使用 json.loads 。你必须先在文档顶部import json

标签: python string pandas dictionary null


【解决方案1】:

据我所知,我不知道这是否适合你。

数据帧:

>>> df
   ID Thing                                Thing_2
0   1   abc  [{"object_1": "a", "object_2": null}]
1   2   def                                   None

输出:

您可以使用 re 模块来实现,但您必须定义需要从列中提取的字符串/字符。

>>> search_list = ['a']
>>> import re

>>> df['Thing_2'] = df.Thing_2.str.extract('({})'.format('|'.join(search_list)), flags=re.IGNORECASE, expand=False).str.lower().fillna('None')
>>> df
   ID Thing Thing_2
0   1   abc       a
1   2   def    None

如果您要针对特定​​列(例如 a)搜索一些字符串/单词,这非常有用。

【讨论】:

  • 你不觉得这对'a'很特殊吗?
  • @Danny,确实是在这种情况下模拟给出的示例,但您不仅限于a,这就是我所说的,您可以传递整个列表,假设您有值提取['a', 'b', 'c' 'd']无论如何...
【解决方案2】:

这应该可行。

import yaml
def change_to_dict(row):
  if pd.notna(row):
     t2 = row
     t2 = t2.strip('[]')
     t2 = yaml.load(t2)

     return list(t2.values())[0]

df['Thing_2'].apply(lambda x: change_to_dict(x))

【讨论】:

    【解决方案3】:

    试试:

    import json
    
    def change_to_dict(row):
        t2 = row['Thing_2']
        if pd.notna(t2):
            t2_content = json.loads(t2)
            return ','.join(filter(bool, t2_content[0].values()))
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多