问题:将包含NaN的Pandas列转换为dtype`int`
我将数据从.csv文件读取到Pandas数据框,如下所示。对于其中一列,id
我想将列类型指定为int
。问题在于该id
系列的值缺失/为空。
当我尝试id
在读取.csv时将列转换为整数时,得到:
df= pd.read_csv("data.csv", dtype={'id': int})
error: Integer column has NA values
或者,我尝试在阅读以下内容后转换列类型,但是这次我得到:
df= pd.read_csv("data.csv")
df[['id']] = df[['id']].astype(int)
error: Cannot convert NA to integer
我该如何解决?
回答 0
整数列中缺少NaN rep是熊猫的“陷阱”。
通常的解决方法是仅使用浮点数。
回答 1
在0.24。+版本中,pandas获得了保留具有缺失值的整数dtypes的功能。
大熊猫可以使用来表示可能缺少值的整数数据Series
:
arr = pd.array([1, 2, np.nan], dtype=pd.Int64Dtype())
pd.Series(arr)
0 1
1 2
2 NaN
dtype: Int64
要将列转换为可为空的整数,请使用:
df['myCol'] = df['myCol'].astype('Int64')
回答 2
我的用例是在装入数据库表之前先整理数据:
df[col] = df[col].fillna(-1)
df[col] = df[col].astype(int)
df[col] = df[col].astype(str)
df[col] = df[col].replace('-1', np.nan)
删除NaN,转换为int,转换为str,然后重新插入NAN。
它虽然不漂亮,但可以完成工作!
回答 3
现在可以创建一个包含NaNs作为int
dtype 的熊猫列,因为它现在已正式添加到熊猫0.24.0中。
pandas 0.24.x发行说明 Quote:“ Pandas已经拥有了持有缺失值的整数dtypes的能力
回答 4
如果绝对要在列中组合整数和NaN,则可以使用“对象”数据类型:
df['col'] = (
df['col'].fillna(0)
.astype(int)
.astype(object)
.where(df['col'].notnull())
)
这将用整数替换NaN(无关紧要),将其转换为int,转换为对象,最后重新插入NaN。
回答 5
如果您可以修改存储的数据,请使用缺少的哨兵值id
。由列名推断出的一个常见用例id
是一个严格大于零的整数,您可以将其0
用作前哨值,以便编写
if row['id']:
regular_process(row)
else:
special_process(row)
回答 6
您可以使用.dropna()
是否可以删除带有NaN值的行。
df = df.dropna(subset=['id'])
或者,使用.fillna()
和.astype()
将NaN替换为值,并将其转换为int。
在处理带有大整数的CSV文件时,我遇到了这个问题,而其中一些缺失(NaN)。不能使用float作为类型,因为我可能会降低精度。
我的解决方案是使用str作为中间类型。然后,您可以在稍后的代码中将字符串转换为int。我将NaN替换为0,但是您可以选择任何值。
df = pd.read_csv(filename, dtype={'id':str})
df["id"] = df["id"].fillna("0").astype(int)
为了进行说明,这是一个示例,说明浮点数可能会降低精度:
s = "12345678901234567890"
f = float(s)
i = int(f)
i2 = int(s)
print (f, i, i2)
输出为:
1.2345678901234567e+19 12345678901234567168 12345678901234567890
回答 7
这里的大多数解决方案都告诉您如何使用占位符整数表示空值。如果不确定整数是否会显示在源数据中,则该方法无济于事。我的方法将格式化不包含其十进制值的浮点数,并将空值转换为无值。结果是一个对象数据类型,当加载到CSV中时,它将看起来像一个带有空值的整数字段。
keep_df[col] = keep_df[col].apply(lambda x: None if pandas.isnull(x) else '{0:.0f}'.format(pandas.to_numeric(x)))
回答 8
我在使用pyspark时遇到了这个问题。由于这是在jvm上运行的代码的python前端,因此它需要类型安全,并且不能选择使用float而不是int。我通过将熊猫包装pd.read_csv
在一个函数中来解决此问题,该函数将使用用户定义的填充值填充用户定义的列,然后再将其转换为所需的类型。这是我最终使用的内容:
def custom_read_csv(file_path, custom_dtype = None, fill_values = None, **kwargs):
if custom_dtype is None:
return pd.read_csv(file_path, **kwargs)
else:
assert 'dtype' not in kwargs.keys()
df = pd.read_csv(file_path, dtype = {}, **kwargs)
for col, typ in custom_dtype.items():
if fill_values is None or col not in fill_values.keys():
fill_val = -1
else:
fill_val = fill_values[col]
df[col] = df[col].fillna(fill_val).astype(typ)
return df
回答 9
首先删除包含NaN的行。然后对剩余的行进行整数转换。最后,再次插入删除的行。希望它能工作
回答 10
import pandas as pd
df= pd.read_csv("data.csv")
df['id'] = pd.to_numeric(df['id'])
回答 11
假设您的DateColumn格式为3312018.0的字符串应转换为03/31/2018。并且,某些记录丢失或为0。
df['DateColumn'] = df['DateColumn'].astype(int)
df['DateColumn'] = df['DateColumn'].astype(str)
df['DateColumn'] = df['DateColumn'].apply(lambda x: x.zfill(8))
df.loc[df['DateColumn'] == '00000000','DateColumn'] = '01011980'
df['DateColumn'] = pd.to_datetime(df['DateColumn'], format="%m%d%Y")
df['DateColumn'] = df['DateColumn'].apply(lambda x: x.strftime('%m/%d/%Y'))