【问题标题】:Nested JSON and Pandas v2嵌套 JSON 和 Pandas v2
【发布时间】:2021-05-25 20:39:56
【问题描述】:

我昨天问了一个关于如何将 JSON 文件转换为数据框的问题,但我问错了问题

Nested JSON and Pandas

我有一个如下所示的 JSON 文件

有两个级别的键(有时重复,有时不重复)

{
"Abaddon the Despoiler": {
    "Abaddon the Despoiler": {
        "model_count": "1",
        "points_value": "220\u2022",
        "movement": "6\"",
        "weapon_skill": "2+",
        "ballistic_skill": "2+",
        "strength": "5",
        "toughness": "5",
        "wounds": "8",
        "attacks": "6",
        "leadership": "10",
        "save": "2+"
    }
},
"Chaos Space Marines": {
    "Chaos Space Marine": {
        "model_count": "4-19",
        "points_value": "14",
        "movement": "6\"",
        "weapon_skill": "3+",
        "ballistic_skill": "3+",
        "strength": "4",
        "toughness": "4",
        "wounds": "1",
        "attacks": "1",
        "leadership": "7",
        "save": "3+"
    },
    "Aspiring Champion": {
        "model_count": "1",
        "points_value": "14",
        "movement": "6\"",
        "weapon_skill": "3+",
        "ballistic_skill": "3+",
        "strength": "4",
        "toughness": "4",
        "wounds": "1",
        "attacks": "2",
        "leadership": "8",
        "save": "3+"
    }
}
}

我想将其转换为如下所示的数据框:

unit model model_count points_value movement weapon_skill ballistic_skill strength toughness wounds attacks leadership save
Abaddon the Despoiler Abaddon the Despoiler 1 220\u2022 6" 2+ 2+ 5 5 8 6 10 +2
Chaos Space Marines Chaos Space Marines 4-19 14 6" 3+ 3+ 4 4 1 1 7 +3
Chaos Space Marines Aspiring Champion 1 14 6" 3+ 3+ 4 4 1 2 8 +3

@azro 昨天为我的问题提供了这个有用的答案,但我问错了问题。在最初的问题中,我想跳过第二级键,所以它看起来像下面

unit model_count points_value movement weapon_skill ballistic_skill strength toughness wounds attacks leadership save
Abaddon the Despoiler 1 220\u2022 6" 2+ 2+ 5 5 8 6 10 +2
Chaos Lord 1 80 6" 2+ 2+ 4 4 5 4 9 +3
d = {'Abaddon the Despoiler': {'Abaddon the Despoiler': {'model_count': '1', 'points_value': '220•', 'movement': '6"', 'weapon_skill': '2+', 'ballistic_skill': '2+', 'strength': '5', 'toughness': '5', 'wounds': '8', 'attacks': '6', 'leadership': '10', 'save': '2+'}}, 
     'Chaos Lord':            {'Chaos Lord':            {'model_count': '1', 'points_value': '80','movement': '6"', 'weapon_skill': '2+', 'ballistic_skill': '2+', 'strength': '4', 'toughness': '4', 'wounds': '5', 'attacks': '4', 'leadership': '9', 'save': '3+'}}}

data = [{'unit': key, **values[key]} for key, values in d.items()]
nycphil = pd.DataFrame(data)

【问题讨论】:

    标签: python json pandas


    【解决方案1】:

    使用嵌套列表推导,将dict附加到嵌套字典的值并传递给DataFrame构造函数:

    L = [{**{'unit': k, 'model': k1}, **v1} for k, v in d.items() for k1, v1 in v.items()]
    
    df = pd.DataFrame(L)
    print (df)
                        unit                  model model_count points_value  \
    0  Abaddon the Despoiler  Abaddon the Despoiler           1         220•   
    1    Chaos Space Marines     Chaos Space Marine        4-19           14   
    2    Chaos Space Marines      Aspiring Champion           1           14   
    
      movement weapon_skill ballistic_skill strength toughness wounds attacks  \
    0       6"           2+              2+        5         5      8       6   
    1       6"           3+              3+        4         4      1       1   
    2       6"           3+              3+        4         4      1       2   
    
      leadership save  
    0         10   2+  
    1          7   3+  
    2          8   3+  
    

    编辑:经过一些测试,error 有一些嵌套值,您可以省略它们,然后输出为:

    with open('chaos-space-marines.json') as f:
        d = json.load(f)
        
    
    L = []
    for k, v in d.items():
        if isinstance(v, dict):
            for k1, v1 in v.items():
                if isinstance(v1, dict):
                    L.append({**{'unit': k, 'model': k1}, **v1})
    
    df = pd.DataFrame(L)
    print (df)
                                       unit                               model  \
    0                 Abaddon the Despoiler               Abaddon the Despoiler   
    1                            Chaos Lord                          Chaos Lord   
    2       Chaos Lord in Terminator Armour     Chaos Lord in Terminator Armour   
    3                                Cypher                              Cypher   
    4                         Daemon Prince                       Daemon Prince   
    ..                                  ...                                 ...   
    122     Hellforged Spartan Assault Tank     Hellforged Spartan Assault Tank   
    123  Hellforged Typhon Heavy Siege Tank  Hellforged Typhon Heavy Siege Tank   
    124                       Kytan Ravager                       Kytan Ravager   
    125                       Chaos Bastion                       Chaos Bastion   
    126                     Noctilith Crown                     Noctilith Crown   
    
        model_count points_value movement weapon_skill ballistic_skill strength  \
    0             1         220•       6"           2+              2+        5   
    1             1           80       6"           2+              2+        4   
    2             1           95       5"           2+              2+        4   
    3             1          85•       7"           2+              2+        4   
    4             1          150       8"           2+              2+        7   
    ..          ...          ...      ...          ...             ...      ...   
    122           1          320        *            *               *        8   
    123           1          720        *            *               *        8   
    124           1          430        *           3+              3+        *   
    125           1          150        -            -              5+        -   
    126           1           85        -            -              4+        -   
    
        toughness wounds attacks leadership save  
    0           5      8       6         10   2+  
    1           4      5       4          9   3+  
    2           4      6       4          9   2+  
    3           4      5       4          9   3+  
    4           6      8       4         10   3+  
    ..        ...    ...     ...        ...  ...  
    122         8     20       4          9   2+  
    123         9     22       7          9   2+  
    124         8     22       *          9   3+  
    125        10     20       0          6   4+  
    126         8     14       -          -   3+  
    
    [127 rows x 13 columns]
    

    编辑:

    您还可以通过else 语句检查有问题的值(为什么原始解决方案失败):

    with open('chaos-space-marines.json') as f:
        d = json.load(f)
    
    L = []
    for k, v in d.items():
        if isinstance(v, dict):
            for k1, v1 in v.items():
                if isinstance(v1, dict):
                    L.append({**{'unit': k, 'model': k1}, **v1})
                else:
                    print ('inner loop')
                    print (v1)
        else:
            print ('outer loop')
            print (v)
    
    df = pd.DataFrame(L)
    

    【讨论】:

    • 嘿,所以这适用于我随问题提供的子集数据,但它不适用于实际数据源,我不确定为什么 kaggle.com/cjblue83/…
    • 使用循环或列表理解方法我得到一个错误TypeError: 'str' object is not a mapping
    • 所以之前的解决方案是因为某些对象中没有内部字典而陷入困境?并且正在将“错误”读取为无法迭代的字符串?
    • @Keagan - 没错,我可以添加一些证明。给我一点时间。
    • @Keagan - 添加到答案中。
    猜你喜欢
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 2021-06-28
    • 2014-04-15
    • 2020-07-21
    • 2019-04-24
    相关资源
    最近更新 更多