我知道这个问题已经被问过很多次了。我试过几种解决方案,但我都不能解决我的问题。
我有一个大的嵌套JSON文件(1.4GB),我想让它平面,然后将其转换为CSV文件。
JSON结构如下所示:
{
"company_number": "12345678",
"data": {
"address": {
"address_line_1": "Address 1",
"locality": "Henley-On-Thames",
"postal_code": "RG9 1DP",
"premises": "161",
"region": "Oxfordshire"
},
"country_of_residence": "England",
"date_of_birth": {
"month": 2,
"year": 1977
},
"etag": "26281dhge33b22df2359sd6afsff2cb8cf62bb4a7f00",
"kind": "individual-person-with-significant-control",
"links": {
"self": "/company/12345678/persons-with-significant-control/individual/bIhuKnFctSnjrDjUG8n3NgOrl"
},
"name": "John M Smith",
"name_elements": {
"forename": "John",
"middle_name": "M",
"surname": "Smith",
"title": "Mrs"
},
"nationality": "Vietnamese",
"natures_of_control": [
"ownership-of-shares-50-to-75-percent"
],
"notified_on": "2016-04-06"
}
}
我知道这很容易用pandas
模块完成,但我对它不熟悉。
已编辑
所需的输出应该如下所示:
company_number, address_line_1, locality, country_of_residence, kind,
12345678, Address 1, Henley-On-Thamed, England, individual-person-with-significant-control
注意,这只是简短的版本,输出应该包含所有字段。
5条答案
按热度按时间kh212irz1#
请向下滚动查看更新、更快的解决方案
这是一个比较老的问题,但我整晚都在为类似的情况而挣扎,想得到一个令人满意的结果,我得出了这个结论:
说明:
cross_join**函数是我发现的一种执行笛卡尔积的简洁方法。(第10页)
json_to_dataframe函数使用panda Dataframe 来完成逻辑。在我的例子中,json是深度嵌套的,我想把字典key:value对拆分成列,但是我想把列表转换成列的行--因此有了concat --然后我把它与上层交叉连接,这样就增加了记录数,这样列表中的每个值都有自己的行,而前面的列是相同的。
递归创建的堆栈与下面的堆栈交叉联接,直到返回最后一个堆栈。
然后,使用表格格式的 Dataframe ,可以使用**”df.to_csv()"** Dataframe 对象方法轻松转换为CSV。
这应该适用于深度嵌套的JSON,能够通过上面描述的逻辑将其规范化为行。
我希望有一天,这能帮助到一些人。只是想给予这个令人敬畏的社区。
-———————————————————————————————————————————————————————————————————————————————————————————-
稍后编辑:全新解决方案
我回到这个主题,因为虽然dataframe选项可以工作,但它花了应用几分钟来解析不太大的JSON数据。因此,我想到做dataframe所做的,但由我自己:
输出:
正如上面所做的那样,cross_join函数做的事情与 Dataframe 解决方案中的几乎相同,但没有 Dataframe ,因此速度更快。
我添加了flatten_list生成器,因为我想确保JSON数组都很好,并且是扁平的,然后作为一个字典列表提供,该列表由一次迭代中的前一个键组成,然后分配给列表的每个值。在本例中,这非常类似于pandas.concat的行为。
主函数json_to_dataframe中的逻辑和以前一样,需要改变的只是将 Dataframe 执行的操作作为编码函数。
此外,在 Dataframe 解决方案中,我没有将前面的标题附加到嵌套对象,但除非您100%确定列名中没有冲突,否则这是非常强制性的。
我希望这能有所帮助:)。
EDIT:修改了cross_join函数来处理嵌套列表为空的情况,基本上保持了之前的结果集不变。即使在示例JSON数据中添加了空的JSON列表,输出也没有变化。谢谢@Nazmus Sakib 指出。
jucafojl2#
对于给定的JSON数据,可以通过解析JSON结构来返回所有叶节点的列表。
这假设你的结构在整个过程中是一致的,如果每个条目可以有不同的字段,请参见第二种方法。
例如:
如果您的JSON数据是您给定格式的条目列表,那么您应该得到如下输出:
如果每个条目都包含不同的(或可能丢失的)字段,则更好的方法是使用
DictWriter
。在这种情况下,需要处理所有条目以确定可能的fieldnames
的完整列表,从而可以写入正确的头。wnavrhmk3#
你可以使用panda库的json_normalize函数来扁平化这个结构体,然后按照你的意愿来处理它。例如:
它为您提供:
knpiaxh14#
提到Bogdan Mircea的回答,
这段代码几乎达到了我的目的!但是当它在嵌套的json中遇到一个空列表时,它返回一个空的 Dataframe 。
您可以通过在代码中添加以下内容来轻松解决这个问题
c86crjj05#