gpt4 book ai didi

Python pandas 带 to_csv 的大 float

转载 作者:行者123 更新时间:2023-12-01 02:35:52 28 4
gpt4 key购买 nike

我有一个 recurring problem将 Python 中的大量数据保存到 csv 中。这些数字是毫秒纪元时间戳,我无法转换或截断,必须以这种格式保存。由于带有毫秒时间戳的列也包含一些 NaN 值,pandas 会自动将它们转换为 float (请参阅“支持整数 NA”下的陷阱中的 the documentation

我似乎无法避免这种行为,所以我的问题是,在使用 df.to_csv 时如何将这些数字保存为整数值,即没有小数点或尾随零?我在同一数据框中有不同 float 精度数字的列,我不想丢失那里的信息。在 to_csv 中使用 float_format 参数似乎对我的数据框中的所有浮点列应用相同的格式。

一个例子:

>>> df = pd.DataFrame({'a':[1.25, 2.54], 'b':[1424380449437, 1425510731187]})
>>> df['b'].dtype
Out[1]: dtype('int64')
>>> df.loc[2] = np.NaN
>>> df
Out[1]:
a b
0 1.25 1.424380e+12
1 2.54 1.425511e+12
2 NaN NaN
>>> df['b'].dtype
dtype('float64')
>>> df.to_csv('test.csv')
>>> with open ('test.csv') as f:
... for line in f:
... print(line)
,a,b
0,1.25,1.42438044944e+12
1,2.54,1.42551073119e+12
2,,

如您所见,我丢失了纪元时间戳最后两位数字的精度。

最佳答案

同时pd.to_csv没有参数来更改各个列的格式,pd.to_string做。这有点麻烦,对于非常大的 DataFrame 可能会出现问题,但您可以使用它来生成格式正确的字符串,然后将该字符串写入文件(如 answer 中针对类似问题的建议)。 to_stringformatters 参数采用函数字典来格式化各个列。在您的情况下,您可以为 "b" 列编写自己的自定义格式化程序,而保留其他列的默认值。这个格式化程序可能看起来有点像这样:

def printInt(b):
if pd.isnull(b):
return "NaN"
else:
return "{:d}".format(int(b))

现在您可以使用它来生成字符串:

df.to_string(formatters={"b": printInt}, na_rep="NaN")

给出:

'      a             b\n0  1.25 1424380449437\n1  2.54 1425510731187\n2   NaN           NaN'

您可以看到仍然存在问题,即这不是逗号分隔的,并且 to_string 实际上没有参数来设置自定义分隔符,但这可以通过正则表达式轻松修复:

import re
re.sub("[ \t]+(NaN)?", ",",
df.to_string(formatters={"b": printInt}, na_rep="NaN"))

给出:

',a,b\n0,1.25,1424380449437\n1,2.54,1425510731187\n2,,'

现在可以将其写入文件中:

with open("/tmp/test.csv", "w") as f:
print(re.sub("[ \t]+(NaN)?", ",",
df.to_string(formatters={"b": printInt}, na_rep="NaN")),
file=f)

这会产生你想要的结果:

,a,b  
0,1.25,1424380449437
1,2.54,1425510731187
2,,
<小时/>

如果您想在 csv 文件中保留 NaN,只需更改正则表达式即可:

with open("/tmp/test.csv", "w") as f:
print(re.sub("[ \t]+", ",",
df.to_string(formatters={"b": printInt}, na_rep="NaN")),
file=f)

将给出:

,a,b
0,1.25,1424380449437
1,2.54,1425510731187
2,NaN,NaN
<小时/>

如果您的 DataFrame 之前包含带有空格的字符串,则稳健的解决方案并不那么容易。您可以在每个值前面插入另一个字符,该字符指示下一个条目的开始。例如,如果所有字符串中只有单个空格,则可以使用另一个空格。这会将代码更改为:

import pandas as pd
import numpy as np
import re

df = pd.DataFrame({'a a':[1.25, 2.54], 'b':[1424380449437, 1425510731187]})
df.loc[2] = np.NaN

def printInt(b):
if pd.isnull(b):
return " NaN"
else:
return " {:d}".format(int(b))

def printFloat(a):
if pd.isnull(a):
return " NaN"
else:
return " {}".format(a)

with open("/tmp/test.csv", "w") as f:
print(re.sub("[ \t][ \t]+", ",",
df.to_string(formatters={"a": printFloat, "b": printInt},
na_rep="NaN", col_space=2)),
file=f)

这会给出:

,a a,b
0,1.25,1424380449437
1,2.54,1425510731187
2,NaN,NaN

关于Python pandas 带 to_csv 的大 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46236711/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com