【发布时间】:2021-01-02 07:55:41
【问题描述】:
考虑以下操作顺序:
- 创建一个包含两列的数据框,其类型为
int64、float64 - 通过将所有列转换为
object创建一个新框架 - 检查新的数据框
- 保留新的数据框
- 期望第二列得到持久化,如第三步所示:即作为字符串,而不是作为 float64
如下图所示:
# Step 1
df = pd.DataFrame.from_dict({'a': [3, 2, 1, 0], 'b': [1, 500.43, 256.13, 5]})
# Step 2
df2 = df.astype(object)
# Step 3
df2.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 a 4 non-null object
1 b 4 non-null object
dtypes: object(2)
memory usage: 192.0+ bytes
# NOTE notice how column `b` is rendered
df2
a b
0 3 1
1 2 500.43
2 1 256.13
3 0 5
# Step 4
df2.to_csv("/tmp/df2", index=False, sep="\t")
现在让我们检查生成的输出:
$ cat df2
a b
3 1.0
2 500.43
1 256.13
0 5.0
注意列b 是如何保留的:即使数据类型为object,小数位仍然存在于整数中。为什么会这样?我在这里错过了什么?
我将 Pandas 1.1.2 与 Python 3.7.9 一起使用。
【问题讨论】:
-
将类型更改为对象不会更改数据框中实际存储的内容,它只会更改列的打印方式。
-
谢谢@cs95。如何将 float64 转换为字符串,以使整数省略零?
-
有一些方法,但它们并不漂亮。您是要修复单列还是多列?
-
您可以将 float cols 转换为字符串并去掉小数位:
df.select_dtypes('float').astype(str).apply(lambda x: x.str.rstrip('.0')) -
@cs95 是迂腐的,它确实改变了存储在数据框中的内容。在
df中,您有一个dtype 为numpy.float64的列,由pandas 包装的原始缓冲区由一个64 位浮点数数组组成。当您执行astype(object)时,底层缓冲区将转换为 PyObject 指针数组。这些都指向 pythonfloat对象。所以数据确实改变了。