为什么 pandas.to_csv 在尝试保留 NaN 时会丢弃数字?
Why is pandas.to_csv dropping numbers when trying to preserve NaN?
给定一个 pandas 数据帧
df = pd.DataFrame([(290122, 0.20, np.nan),
(1900, 1.20, "ABC")],
columns = ("number", "x", "class")
)
number x class
0 290122 0.2 NaN
1 1900 1.2 ABC
然后将其导出到 csv,我想保留 NaN,例如作为 "NULL" 或 "NaN",
df.to_csv("df.csv", encoding="utf-8", index=False, na_rep="NULL")
然而,打开 csv 我得到以下信息:
也就是说,第一个单元格中数字的最后两位被删除。
这是在文本编辑器中打开的输出:
number,x,class
2901,0.20,NULL
1900,1.20,ABC
如前所述,当删除 na_rep 参数时,我得到了预期的结果:
number,x,class
290122,0.20,
1900,1.20,ABC
在 .csv 文件中,当从 pandas 读取或写入时 - np.nan 在文件中存储为 ''(空字符串),因此不要使用 na_rep='NULL' 而不是再次从 pandas 读取(保存后),执行此操作:
for col in df.columns:
df[col].apply(lambda x: np.nan if x == '' else x)
不过,默认情况下,所有空字符串都被读取为 NaN。这仍然有用 - 只是为了安全起见。
我自己以前遇到过这个问题,发现没有其他方法可以解决这个问题,但如果我找到一个(完美地保存 nan 或 NULL),我会在这里更新。
是的,这实际上是 pandas 1.0.0 中的错误。已在 1.0.1 中修复。请参阅发行说明和 https://github.com/pandas-dev/pandas/issues/25099.
根据您的数据,快速解决方法可能是:
import numpy as np
import pandas as pd
na_rep = 'NULL'
if pd.__version__ == '1.0.0':
na_rep_wrk = 8 * na_rep
data = [(290122, 0.20, 'NULL'), (2**40 - 1, 3.20, 'NULL'), (1900, 1.20, "ABC")]
df = pd.DataFrame(data, columns=("number", "x", "class"))
df.to_csv("df.csv", encoding="utf-8", index=False, na_rep=na_rep_wrk)
df2 = pd.read_csv('df.csv', keep_default_na=False)
assert(np.all(df == df2))
这给出了 csv 文件:
number,x,class
290122,0.2,NULL
109951162777,3.2,NULL
1900,1.2,ABC
给定一个 pandas 数据帧
df = pd.DataFrame([(290122, 0.20, np.nan),
(1900, 1.20, "ABC")],
columns = ("number", "x", "class")
)
number x class
0 290122 0.2 NaN
1 1900 1.2 ABC
然后将其导出到 csv,我想保留 NaN,例如作为 "NULL" 或 "NaN",
df.to_csv("df.csv", encoding="utf-8", index=False, na_rep="NULL")
然而,打开 csv 我得到以下信息: 也就是说,第一个单元格中数字的最后两位被删除。
number,x,class
2901,0.20,NULL
1900,1.20,ABC
如前所述,当删除 na_rep 参数时,我得到了预期的结果:
number,x,class
290122,0.20,
1900,1.20,ABC
在 .csv 文件中,当从 pandas 读取或写入时 - np.nan 在文件中存储为 ''(空字符串),因此不要使用 na_rep='NULL' 而不是再次从 pandas 读取(保存后),执行此操作:
for col in df.columns:
df[col].apply(lambda x: np.nan if x == '' else x)
不过,默认情况下,所有空字符串都被读取为 NaN。这仍然有用 - 只是为了安全起见。
我自己以前遇到过这个问题,发现没有其他方法可以解决这个问题,但如果我找到一个(完美地保存 nan 或 NULL),我会在这里更新。
是的,这实际上是 pandas 1.0.0 中的错误。已在 1.0.1 中修复。请参阅发行说明和 https://github.com/pandas-dev/pandas/issues/25099.
根据您的数据,快速解决方法可能是:
import numpy as np
import pandas as pd
na_rep = 'NULL'
if pd.__version__ == '1.0.0':
na_rep_wrk = 8 * na_rep
data = [(290122, 0.20, 'NULL'), (2**40 - 1, 3.20, 'NULL'), (1900, 1.20, "ABC")]
df = pd.DataFrame(data, columns=("number", "x", "class"))
df.to_csv("df.csv", encoding="utf-8", index=False, na_rep=na_rep_wrk)
df2 = pd.read_csv('df.csv', keep_default_na=False)
assert(np.all(df == df2))
这给出了 csv 文件:
number,x,class
290122,0.2,NULL
109951162777,3.2,NULL
1900,1.2,ABC