【发布时间】:2019-08-22 14:42:39
【问题描述】:
我正在创建一个小的 Pandas DataFrame 并向其中添加一些应该是整数的数据。但即使我非常努力地将 dtype 显式设置为 int 并且只提供 int 值,它总是最终变成浮点数。这对我来说毫无意义,而且行为似乎也不完全一致。
考虑以下 Python 脚本:
import pandas as pd
df = pd.DataFrame(columns=["col1", "col2"]) # No dtype specified.
print(df.dtypes) # dtypes are object, since there is no information yet.
df.loc["row1", :] = int(0) # Add integer data.
print(df.dtypes) # Both columns have now become int64, as expected.
df.loc["row2", :] = int(0) # Add more integer data.
print(df.dtypes) # Both columns are now float64???
print(df) # Shows as 0.0.
# Let's try again, but be more specific.
del df
df = pd.DataFrame(columns=["col1", "col2"], dtype=int) # Explicit set dtype.
print(df.dtypes) # For some reason both colums are already float64???
df.loc["row1", :] = int(0)
print(df.dtypes) # Both colums still float64.
# Output:
"""
col1 object
col2 object
dtype: object
col1 int64
col2 int64
dtype: object
col1 float64
col2 float64
dtype: object
col1 col2
row1 0.0 0.0
row2 0.0 0.0
col1 float64
col2 float64
dtype: object
col1 float64
col2 float64
dtype: object
"""
我可以通过在最后执行df = df.astype(int) 来修复它。还有其他方法可以修复它。但这不应该是必要的。我试图弄清楚我做错了什么,导致列首先变成浮动。
发生了什么事?
Python 版本 3.7.1 熊猫版本 0.23.4
编辑:
我想也许有些人误解了。此 DataFrame 中从来没有任何 NaN 值。它创建后立即如下所示:
Empty DataFrame
Columns: [col1, col2]
Index: []
这是一个空数据框,df.shape=0,但其中没有 NaN,只是还没有行。
我还发现了更糟糕的事情。即使我在添加数据使其变为 int 后执行df = df.astype(int),只要我添加更多数据,它就会再次变为浮动!
df = pd.DataFrame(columns=["col1", "col2"], dtype=int)
df.loc["row1", :] = int(0)
df.loc["row2", :] = int(0)
df = df.astype(int) # Force it back to int.
print(df.dtypes) # It is now ints again.
df.loc["row3", :] = int(0) # Add another integer row.
print(df.dtypes) # It is now float again???
# Output:
"""
col1 int32
col2 int32
dtype: object
col1 float64
col2 float64
dtype: object
"""
suggested fix in version 0.24 似乎与我的问题无关。该功能与 Nullable Integer 数据类型有关。我的数据中没有 NaN 或 None 值。
【问题讨论】:
-
如果存在 nan 或空行,则假定为浮点数。这是针对较新版本修复的,请参阅this
-
我对这个问题的答案很感兴趣。但是,如果您使用零填充数据框,并将框架设置为 int,则修改行不会更改为浮动。似乎只添加行。 .loc 试图访问一个不存在的索引,所以我猜浮动是在创建新的行索引时出现的。
-
@run-out 是的,这也是我观察到的。也许您不应该像我正在做的那样将行附加到 DataFrame 中的新索引。但显然可以这样做,因此您会认为它要么得到妥善处理,要么引发警告/异常。
-
每当您向 DataFrame 添加行(或连接两个 df 等)时,Pandas 都会重铸所有 dtype。据推测,它对某些事情感到困惑并默认为浮动。请注意,如果您首先从具有定义索引的空 DataFrame 开始,然后按照您的描述添加值,您将获得 dtype int64。
-
阅读 indexing.py 从文档字符串中可以清楚地看出 .loc 仅用于切片,而不是添加行或列。它为类 _LocIndexer 声明了以下 _valid_types = ("labels (MUST BE IN THE INDEX) 。在大写字母中不少于!可以以这种方式创建行的事实似乎超出了 .loc 的范围, ,所以像 int 这样的小故障会发生并且将会发生。
标签: python pandas types type-conversion