繁体   English   中英

熊猫 to_dict 修改数字

[英]Pandas to_dict modifying numbers

我一直在玩一个函数,它接收 CSV 数据并使用 pandas to_dict 函数作为实现将数据转换为 JSON 的最终目标的步骤之一。 问题是它正在修改数字(例如 1.6 变成 1.6000000000000001)。 我并不担心准确性的损失,但是因为用户会看到数字的变化,所以它看起来......很业余。

我知道这是以前在这里出现过的东西,但这是 2 年前的事情,并没有真正得到很好的回答,而且我还有一个额外的问题——我希望转换为字典的数据框可以是任何组合数据类型。 因此,先前解决方案的问题是:

  1. 将所有数字转换为对象仅在您不需要使用数字时才有效 - 我想要计算总和和平均值的选项,这会重新引入加法小数问题
  2. 根据用户提供的数据,强制将数字四舍五入到 x 位小数会降低准确性或添加额外的不必要的 0

所以,在高层次上,我的问题是:

有没有更好的方法来确保数字不被修改,而是保存在数字数据类型中? 首先是更改我导入 CSV 数据的方式的问题吗? 当然,我忽略了一个简单的解决方案?

这是一个将重现此错误的简单脚本:

import pandas as pd

import sys
if sys.version_info[0] < 3:
    from StringIO import StringIO
else:
    from io import StringIO

CSV_Data = "Index,Column_1,Column_2,Column_3,Column_4,Column_5,Column_6,Column_7,Column_8\nindex_1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8\nindex_2,2.1,2.2,2.3,2.4,2.5,2.6,2.7,2.8\nindex_3,3.1,3.2,3.3,3.4,3.5,3.6,3.7,3.8\nindex_4,4.1,4.2,4.3,4.4,4.5,4.6,4.7,4.8"

input_data = StringIO(CSV_Data)
df = pd.DataFrame.from_csv(path = input_data, header = 0, sep=',', index_col=0, encoding='utf-8')
print(df.to_dict(orient = 'records'))

您可以使用pd.io.json.dumps来处理带有 pandas 对象的嵌套字典。

让我们创建一个包含数据帧记录和自定义指标的summary字典。

In [137]: summary = {'df': df.to_dict(orient = 'records'), 'df_metric': df.sum() / df.min()}

In [138]: summary['df_metric']
Out[138]:
Column_1    9.454545
Column_2    9.000000
Column_3    8.615385
Column_4    8.285714
Column_5    8.000000
Column_6    7.750000
Column_7    7.529412
Column_8    7.333333
dtype: float64

In [139]: pd.io.json.dumps(summary)
Out[139]: '{"df":[{"Column_7":1.7,"Column_6":1.6,"Column_5":1.5,"Column_4":1.4,"Column_3":1.3,"Column_2":1.2,"Column_1":1.1,"Column_8":1.8},{"Column_7":2.7,"Column_6":2.6,"Column_5":2.5,"Column_4":2.4,"Column_3":2.3,"Column_2":2.2,"Column_1":2.1,"Column_8":2.8},{"Column_7":3.7,"Column_6":3.6,"Column_5":3.5,"Column_4":3.4,"Column_3":3.3,"Column_2":3.2,"Column_1":3.1,"Column_8":3.8},{"Column_7":4.7,"Column_6":4.6,"Column_5":4.5,"Column_4":4.4,"Column_3":4.3,"Column_2":4.2,"Column_1":4.1,"Column_8":4.8}],"df_metric":{"Column_1":9.4545454545,"Column_2":9.0,"Column_3":8.6153846154,"Column_4":8.2857142857,"Column_5":8.0,"Column_6":7.75,"Column_7":7.5294117647,"Column_8":7.3333333333}}'

使用double_precision改变双精度的最大数字精度。 注意。 df_metric值。

In [140]: pd.io.json.dumps(summary, double_precision=2)
Out[140]: '{"df":[{"Column_7":1.7,"Column_6":1.6,"Column_5":1.5,"Column_4":1.4,"Column_3":1.3,"Column_2":1.2,"Column_1":1.1,"Column_8":1.8},{"Column_7":2.7,"Column_6":2.6,"Column_5":2.5,"Column_4":2.4,"Column_3":2.3,"Column_2":2.2,"Column_1":2.1,"Column_8":2.8},{"Column_7":3.7,"Column_6":3.6,"Column_5":3.5,"Column_4":3.4,"Column_3":3.3,"Column_2":3.2,"Column_1":3.1,"Column_8":3.8},{"Column_7":4.7,"Column_6":4.6,"Column_5":4.5,"Column_4":4.4,"Column_3":4.3,"Column_2":4.2,"Column_1":4.1,"Column_8":4.8}],"df_metric":{"Column_1":9.45,"Column_2":9.0,"Column_3":8.62,"Column_4":8.29,"Column_5":8.0,"Column_6":7.75,"Column_7":7.53,"Column_8":7.33}}'

您可以使用orient='records/index/..'来处理数据帧 -> to_json 构造。

In [144]: pd.io.json.dumps(summary, orient='records')
Out[144]: '{"df":[{"Column_7":1.7,"Column_6":1.6,"Column_5":1.5,"Column_4":1.4,"Column_3":1.3,"Column_2":1.2,"Column_1":1.1,"Column_8":1.8},{"Column_7":2.7,"Column_6":2.6,"Column_5":2.5,"Column_4":2.4,"Column_3":2.3,"Column_2":2.2,"Column_1":2.1,"Column_8":2.8},{"Column_7":3.7,"Column_6":3.6,"Column_5":3.5,"Column_4":3.4,"Column_3":3.3,"Column_2":3.2,"Column_1":3.1,"Column_8":3.8},{"Column_7":4.7,"Column_6":4.6,"Column_5":4.5,"Column_4":4.4,"Column_3":4.3,"Column_2":4.2,"Column_1":4.1,"Column_8":4.8}],"df_metric":[9.4545454545,9.0,8.6153846154,8.2857142857,8.0,7.75,7.5294117647,7.3333333333]}'

本质上, pd.io.json.dumps将任意对象递归转换为JSON,内部使用ultrajson

我需要用正确的浮点数制作df.to_dict('list') 但是df.to_json()还不支持orient='list' 所以我做以下:

 list_oriented_dict = {
    column: list(data.values())
    for column, data in json.loads(df.to_json()).items()
}

不是最好的方法,但它对我有用。 也许有人有更优雅的解决方案?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM