【问题标题】:convert pandas json column to multiple rows将 pandas json 列转换为多行
【发布时间】:2020-07-09 13:29:56
【问题描述】:
data1 = {0: [{'confident': False, 'iab': 'IAB25-3'}],
 1: [{'confident': False, 'iab': 'IAB6-6'},
  {'confident': True, 'iab': 'IAB6'}],
 2: [{'confident': True, 'iab': 'IAB16-1'},
  {'confident': True, 'iab': 'IAB16'},
  {'confident': False, 'iab': 'IAB9'},
  {'confident': False, 'iab': 'IAB9-28'}]}

上述格式最初是每行中的列表/json 有 = [{'confident': False, 'iab': 'IAB25-3'},{'confident': True, 'iab': 'IAB16'} ] 在 to_dict() 的帮助下转换为字典,从而得到开头提到的数据。 主要问题是集合数组(自信和 iab)可以是 n 次并且 n 是未知的。所以,我无法格式化它。

我正在努力将其转换为以下给定的数据帧格式,但尚未成功。

rowid   confident    iab
0       False        IAB25-3
1       False        IAB6-6
1       True         IAB6
2       True         IAB16-1
2       True         IAB16
2       False        IAB9
2       False        IAB9-28

感谢任何帮助。

【问题讨论】:

    标签: python json pandas data-cleaning data-conversion


    【解决方案1】:

    想法是使用列表推导来扁平化值,并将键值添加到新的rowid 键的字典列表中,因此如果性能很重要,可以传递给DataFrame 构造函数:

    df = pd.DataFrame([dict(**{'rowid':k}, **y) for k, v in data1.items() for y in v])
    
    print (df)
       rowid  confident      iab
    0      0      False  IAB25-3
    1      1      False   IAB6-6
    2      1       True     IAB6
    3      2       True  IAB16-1
    4      2       True    IAB16
    5      2      False     IAB9
    6      2      False  IAB9-28
    

    concat 和字典理解的另一个解决方案应该更好的是字典中的大 DataFrames 很少,但通常 concat 生成许多小的 DataFrames 很慢:

    df = (pd.concat({k: pd.DataFrame(v) for k, v in data1.items()})
            .reset_index(level=1, drop=True)
            .rename_axis('rowid')
            .reset_index())
    print (df)
       rowid  confident      iab
    0      0      False  IAB25-3
    1      1      False   IAB6-6
    2      1       True     IAB6
    3      2       True  IAB16-1
    4      2       True    IAB16
    5      2      False     IAB9
    6      2      False  IAB9-28
    

    【讨论】:

    • 这种方法适用于我的一些 Json 行,但我在使用其他 json (AttributeError: 'NoneType' object has no attribute 'keys') 时遇到此错误有什么帮助吗?
    【解决方案2】:

    这是使用json_normalize的另一种方式:

    dfs = []
    for k, v in data1.items():
        df = pd.json_normalize(v)
        df['rowid'] = k
        dfs.append(df)
    
    df = pd.concat(dfs).reset_index(drop='index')
    print(df)
    
    
       confident      iab  rowid
    0      False  IAB25-3      0
    1      False   IAB6-6      1
    2       True     IAB6      1
    3       True  IAB16-1      2
    4       True    IAB16      2
    5      False     IAB9      2
    6      False  IAB9-28      2
    

    【讨论】:

    • 但我仍然认为concat 这里的解决方案很慢,更快的是更改数据结构并传递给DataFrame 构造函数。
    • 是的 concat 在这里我同意可能会慢一些,但不确定为什么它与预期的输出不匹配?
    • 哦,让我改一下吧:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-21
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多