将JSON数据展平为单独的行

时间:2019-01-29 17:02:46

标签: java python pandas jq flatten

我对使用多层嵌套对象数组使JSON扁平化感兴趣。我理想情况下想在Java中执行此操作,但似乎python中的Pandas库可能对此有所帮助。

有人知道这个好的Java库吗?

我使用pandasjq找到了这篇文章(Create a Pandas DataFrame from deeply nested JSON),我的解决方案几乎可以正常工作,但是我收到的输出与预期不符。这是我的代码示例

json_data = '''{ "id": 1,
"things": [
    {
        "tId": 1,
        "objs": [{"this": 99},{"this": 100}]
    },
    {
        "tId": 2,
        "objs": [{"this": 222},{"this": 22222}]
    }
]
 }'''

rule = """[{id: .id, 
        tid: .things[].tId,
        this: .things[].objs[].this}]"""
out = jq(rule, _in=json_data).stdout
res = pd.DataFrame(json.loads(out))

问题是我收到的输出是这样:

   id   this  tid
0   1     99    1
1   1    100    1
2   1    222    1
3   1  22222    1
4   1     99    2
5   1    100    2
6   1    222    2
7   1  22222    2

我希望看到

   id   this  tid
0   1     99    1
1   1    100    1
3   1    222    2
4   1  22222    2

任何有关如何实现此目的的技巧,不同的解决方案或java选项都会很棒!

谢谢!

克雷格

1 个答案:

答案 0 :(得分:0)

问题在于您的“规则”创建了笛卡尔积,而实际上您希望嵌套迭代。

使用您的输入,下面的jq表达式(使嵌套迭代合理清晰)产生如下所示的输出:

.id as $id
| .things[] as $thing
| $thing.objs[]
| [$id, .this, $thing.tId]
| @tsv

输出

1   99  1
1   100 1
1   222 2
1   22222   2

规则

因此大概您的规则应如下所示:

[{id} + (.things[] | {tid: .tId} + (.objs[] | {this}))]

或者如果您想使嵌套迭代更清晰:

[ .id as $id
  | .things[] as $thing
  | $thing.objs[]
  | {id: $id, this, tid: $thing.tId} ]

在Java中运行jq

除了processBuilder之外,您可能还想看看这些包装器: