【问题标题】:pandas df into nested json大熊猫 df 成嵌套的 json
【发布时间】:2015-10-11 12:11:26
【问题描述】:

there 提出了一个类似的问题,R 中的 user1609452 给出了精彩的回答。不过,这是一个特定的问题。我想扩展这个问题。让我们使用几乎相同的表(MyData):

ID  Location  L_size   L_color    Station    S_size   S_color     Category   C_size   C_color  
1     Alpha     6      #000000      Zeta       3      #333333      Big       0.63     #306100
2     Alpha     6      #000000      Zeta       3      #333333     Medium     0.43     #458b00
3     Alpha     6      #000000      Zeta       3      #333333     small      0.47     #6aa232
4     Alpha     6      #000000      Yota       3      #4c4c4c      Big       0.85     #306100
5     Alpha     6      #000000      Yota       3      #4c4c4c     Medium     0.19     #458b00
6     Alpha     6      #000000      Yota       3      #4c4c4c     small      0.89     #6aa232
7      Beta     6      #191919      Theta      4      #666666      Big       0.09     #306100
8      Beta     6      #191919      Theta      4      #666666     Medium     0.33     #458b00
9      Beta     6      #191919      Theta      4      #666666     small      0.79     #6aa232
10     Beta     6      #191919      Theta      4      #666666      Big       0.89     #306100
11     Beta     6      #191919       Meta      3      #7f7f7f     Medium     0.71     #458b00
12     Beta     6      #191919       Meta      3      #7f7f7f     small      0.59     #6aa232

每个类别都有一个或多个属性(这里只有一个:大小)。我想要的是报告json文件中每个父/子的大小:

       {
 "name":"MyData",
 "size":12,
 "color":"#ffffff"
 "children":[
   {
     "name":"Alpha",
     "size":6,
     "color":"#000000"
     "children":[
        {
           "name":"Zeta",
           "size":3,
           "color":"#333333"
           "children":[
              {
                 "name":"Big",
                 "size":0.63,
                 "color":"#306100"
              },
...

等等。 我无法在 R 和 pandas 中实现它......有什么想法吗?

编辑: 我的目标是将各种信息与儿童联系起来,而不仅仅是大小。我为每个主列添加了一个颜色列。我的初始数据框很大并且包含很多信息,但为了清楚起见,我无法将其粘贴到此处。

第二次编辑:克里斯布回答 它几乎奏效了!很棒的更新。 json 文件仍然没有正确上传到我的 javascript 文件中。文件好像倒过来了(mydata在最后),来自parent的信息是前后children信息:

{  
   "children":[  
      {  
         "color":"#000000",
         "children":[  
            {  
               "color":"#4c4c4c",
               "children":{  
                  "color":"#306100",
                  "name":"Big",
                  "size":0.85
               },
               "name":"Yota",
               "size":3
            },
            {  
               "color":"#333333",
               "children":{  
                  "color":"#306100",
                  "name":"Big",
                  "size":0.63
               },
               "name":"Zeta",
               "size":3
            }
         ],
         "name":"Alpha",
         "size":6
      },
      {  
         "color":"#191919",
         "children":[  
            {  
               "color":"#7f7f7f",
               "children":{  
                  "color":"#458b00",
                  "name":"Medium",
                  "size":0.71
               },
               "name":"Meta",
               "size":3
            },
            {  
               "color":"#666666",
               "children":{  
                  "color":"#306100",
                  "name":"Big",
                  "size":0.09
               },
               "name":"Theta",
               "size":4
            }
         ],
         "name":"Beta",
         "size":6
      }
   ],
   "name":"MyData",
   "size":12

最后编辑:工作正常。 Chris 在更新脚本时删除了他编写的脚本的最后一部分,所以就在这里。谢谢克里斯!

data = {'name': 'MyData',
        'size': len(MyData),
        'children': make_children(MyData, levels)}

print json.dumps(data)

【问题讨论】:

    标签: javascript python json r pandas


    【解决方案1】:

    首先,您需要对构成每个级别的内容进行某种映射。我正在使用定义 "name" 的列的元组以及您想要从该级别获得的其他属性的前缀,就像这样。

    levels = [('Location', 'L_'),
              ('Station', 'S_'),
              ('Category', 'C_')]
    

    然后,它是一个类似的递归函数,只是现在在每个步骤中都会提取额外的列(查找以前缀开头的列)并通过压缩列/值将其添加到树中。有清理的余地,但至少应该给出一个想法。

    def make_children(df, levels):
        if len(levels) == 1:
            name, prefix = levels[0]
            level_cols = [name] + [c for c in df if c.startswith(prefix)]
            df = df[level_cols]
            key_names = ['name'] + [c.strip(prefix) for c in level_cols[1:]]
            return dict(zip(key_names, df.values[0]))
        else:
            h, tail = levels[0], levels[1:]
            name, prefix = h
            level_cols = [name] + [c for c in df if c.startswith(prefix)]
    
            data = []
            for keys, df_gb in df.groupby(level_cols):
                key_names = ['name'] + [c.strip(prefix) for c in level_cols[1:]]
                d = dict(zip(key_names, keys))
                d['children'] = make_children(df_gb, tail)
                data.append(d)
            return data    
    

    【讨论】:

    • 谢谢克里斯。您从上面的链接中找到了避免使用 R 脚本的好方法。我的示例不够好,因为您的脚本巧妙地从 df 的长度中获取了大小。我想要的不仅仅是尺寸...我会编辑问题...
    • 克里斯,我想我们已经到了,但是虽然 json 是有效的,但我的 javascript 没有正确上传它。请参阅我的第二次更新。谢谢!
    • @Sara - JSON 是无序的,所以这不是问题。但是,一切都必须是字符串。在转换为 dict/JSON 之前尝试执行 df = df.astype(str)
    • 我的错,chrome 阻止了 json 导入...效果很好!非常感谢克里斯!
    猜你喜欢
    • 2019-03-12
    • 2018-05-05
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 2014-08-13
    • 2017-03-28
    • 2020-12-28
    相关资源
    最近更新 更多