熊猫在 to_json 时删除空值

Posted

技术标签:

【中文标题】熊猫在 to_json 时删除空值【英文标题】:Pandas remove null values when to_json 【发布时间】:2015-09-03 22:30:12 【问题描述】:

我实际上有一个 pandas 数据框,我想将它保存为 json 格式。 从熊猫文档中它说:

注意 NaN、NaT 和 None 将被转换为 null 和 datetime 对象将根据 date_format 和 date_unit 进行转换 参数

然后使用 orient 选项records 我有这样的东西

["A":1,"B":4,"C":7,"A":null,"B":5,"C":null,"A":3,"B":null,"C":null]

是否可以改为:

["A":1,"B":4,"C":7,"B":5,"A":3]'

谢谢

【问题讨论】:

你能在写 JSON 之前先dropna 空值吗? @katrielalex 我认为它比这更复杂,dropna 将删除行或列,OP 询问是否可以删除单个元素,因此最终的 json 甚至没有该元素的条目 @EdChum 是的,你是对的 我唯一能想到的就是为每一行生成目录,您可以在其中删除 NaN 值,或者解析 json 字典并删除条目,我不认为 dfs 将允许每行的尺寸不同的形式。考虑一下,您可以为不包含 NaN 值的每一行创建一个字典,然后在该列上调用 to_json,让我试试这个 df.apply(lambda x: [x.dropna()], axis=1).to_json() 接近你想要的? 【参考方案1】:

上述解决方案实际上不会产生“记录”格式的结果。此解决方案也使用 json 包,但会产生原始问题中要求的结果。

import pandas as pd
import json

json.dumps([row.dropna().to_dict() for index,row in df.iterrows()])

此外,如果您想包含索引(并且您使用的是 Python 3.5+),您可以这样做:

json.dumps(['index':index, **row.dropna().to_dict() for index,row in df.iterrows()])

【讨论】:

非常好!这帮助我将一个高度稀疏的数据透视表变成了一个 No-SQL 就绪插入,只需一行 :) 这是天才。熊猫应该有这个选项。谢谢。【参考方案2】:

以下内容接近您想要的,本质上我们创建了一个非 NaN 值的列表,然后在此调用 to_json

In [136]:
df.apply(lambda x: [x.dropna()], axis=1).to_json()

Out[136]:
'"0":["a":1.0,"b":4.0,"c":7.0],"1":["b":5.0],"2":["a":3.0]'

在此处创建列表是必要的,否则它将尝试将结果与您的原始 df 形状对齐,这将重新引入您想要避免的 NaN 值:

In [138]:
df.apply(lambda x: pd.Series(x.dropna()), axis=1).to_json()

Out[138]:
'"a":"0":1.0,"1":null,"2":3.0,"b":"0":4.0,"1":5.0,"2":null,"c":"0":7.0,"1":null,"2":null'

同时在dropna的结果上调用list会用形状广播结果,比如填充:

In [137]:
df.apply(lambda x: list(x.dropna()), axis=1).to_json()

Out[137]:
'"a":"0":1.0,"1":5.0,"2":3.0,"b":"0":4.0,"1":5.0,"2":3.0,"c":"0":7.0,"1":5.0,"2":3.0'

【讨论】:

谢谢它的工作,但对于方向选项列标签没有显示,因为它假设你的输入是系列类型 抱歉,您是说df.apply(lambda x: [x.dropna()], axis=1).to_json(orient='columns') 不起作用还是没有给您想要的输出? 它可以工作,但是当我将方向选项设置为“记录”时,它没有给出所需的输出 是的,这很棘手,对此无能为力。就像我说的那样,另一件事是对结果字典进行后处理并删除嵌套字典中具有空条目的条目是一种可能性【参考方案3】:

投票最多的答案使用iterrows(),由于在大型数据帧上的性能不佳,这不被视为最佳做法。以下解决方案仅在我的用例上具有类似的性能,但对于其他数据集可能会更好?

所以可以改用

df.agg(lambda x: x.dropna().to_dict(), axis=1)

将数据框转换为一系列没有空值的字典。然后可以将系列转换为 JSON 列表:

import json
json.dumps(list(df.agg(lambda x: x.dropna().to_dict(), axis=1)))

【讨论】:

【参考方案4】:

我遇到了同样的问题,我的解决方案是使用 json 模块而不是 pd.DataFrame.to_json()

我的解决办法是

    DataFrame转dict时去掉NaN值,然后 使用 json.dumps() 将 dict 转换为 json

代码如下:

import pandas as pd
import json
from pandas import compat

def to_dict_dropna(df):
   return int(k): v.dropna().astype(int).to_dict() for k, v in compat.iteritems(df)

json.dumps(to_dict_dropna(df))

【讨论】:

以上是关于熊猫在 to_json 时删除空值的主要内容,如果未能解决你的问题,请参考以下文章

pandas 怎么处理表格中的空值

主键约束,外键约束,空值约束,默认值约束,唯一约束,检查约束的各个作用是啥?

熊猫合并用空值填充新数据框

MS ACCESS 2016 - 使用 Null 进行查询的标准

带有应用功能的熊猫空值检查

那些年我们踩过的坑,SQL 中的空值陷阱!