Python 将包含NaN的列转换为dtype`int`
我将数据从.csv文件读取到熊猫数据框,如下所示。对于其中一列,即Python 将包含NaN的列转换为dtype`int`,python,pandas,na,Python,Pandas,Na,我将数据从.csv文件读取到熊猫数据框,如下所示。对于其中一列,即id,我想将列类型指定为int。问题在于id序列缺少/空值 当我在读取.csv时尝试将id列强制转换为整数时,我得到: df= pd.read_csv("data.csv", dtype={'id': int}) error: Integer column has NA values 或者,在阅读以下内容后,我尝试转换列类型,但这次我得到: df= pd.read_csv("data.csv") df[['id']] = d
id
,我想将列类型指定为int
。问题在于id
序列缺少/空值
当我在读取.csv时尝试将id
列强制转换为整数时,我得到:
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
如何解决这个问题?整数列中缺少NaN rep是一个问题
通常的解决方法是简单地使用浮点数。如果可以修改存储的数据,请为缺少的
id使用sentinel值。根据列名推断的一个常见用例是,id
是一个严格大于零的整数,您可以使用0
作为哨兵值,以便编写
if row['id']:
regular_process(row)
else:
special_process(row)
假设您的DateColumn格式为332018.0,应将其作为字符串转换为2018年3月31日。并且,某些记录丢失或为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'))
我的用例是在加载到DB表之前对数据进行扫描:
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
这并不漂亮,但它完成了任务 我在使用pyspark时遇到了这个问题。由于这是用于在jvm上运行的代码的python前端,因此需要类型安全性,并且不能使用float而不是int。我解决了这个问题,将pandaspd.read\u 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
首先删除包含NaN的行。然后对其余行执行整数转换。
最后再次插入删除的行。
希望它能工作如果可以删除带有NaN值的行,您可以使用.dropna()
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
如果绝对希望在列中组合整数和NaN,可以使用“object”数据类型:
df['col'] = (
df['col'].fillna(0)
.astype(int)
.astype(object)
.where(df['col'].notnull())
)
这将用一个整数(不管哪个)替换NaN,转换为int,转换为object,最后重新插入NaN。这里的大多数解决方案告诉您如何使用占位符整数来表示空值。如果您不确定整数不会出现在源数据中,那么这种方法是没有帮助的。我的方法将格式化不带小数点的浮点,并将空值转换为无值。结果是一个对象数据类型,当加载到CSV中时,它看起来像一个具有空值的整型字段
keep_df[col] = keep_df[col].apply(lambda x: None if pandas.isnull(x) else '{0:.0f}'.format(pandas.to_numeric(x)))
在版本0.24中,+pandas获得了保存缺失值的整数数据类型的能力
熊猫可以使用表示可能缺少值的整数数据。这是在pandas中实现的扩展类型。它不是整数的默认数据类型,不会被推断;必须将数据类型显式传递到或系列中
:
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')
现在可以创建一个pandas列,其中包含数据类型为dtypeint
,因为它现在正式添加到pandas 0.24.0中
Quote:“熊猫已经获得了保存缺失值的整数数据类型的能力使用pd.to\u numeric()
import pandas as pd
df= pd.read_csv("data.csv")
df['id'] = pd.to_numeric(df['id'])
简单明了从Pandas 1.0.0开始,您现在可以使用Pandas.NA值。这不会强制将缺少值的整列作为浮点数
读取数据时,您需要做的就是:
df= pd.read_csv("data.csv", dtype={'id': 'Int64'})
请注意,“Int64”被引号包围,I大写。这区别于Panda的“Int64”和numpy的Int64
作为补充说明,这也适用于.astype()
这里的文档
试试这个:
df[['id']]=df[['id']].astype(pd.Int64Dtype())
如果您打印的是dtypes
,您将获得id Int64
,而不是正常的一个Int64
我几周前遇到了问题,一些离散的功能被格式化为“object”。这个解决方案似乎有效
for col in discrete:
df[col] = pd.to_numeric(df[col],errors='coerce').astype(pd.Int64Dtype())
如果要在链接方法时使用它,可以使用assign:
df = (
df.assign(col = lambda x: x['col'].astype('Int64'))
)
与许多其他解决方案一样,Int64
的问题是,如果您有null
值,它们将被替换为
值,这些值与默认的'NaN'函数不兼容,如isnull()
或fillna()
。或者,如果将值转换为-1
,则可能会导致删除信息的情况。我的解决方案有点蹩脚,但将提供int
值和np.nan
,从而允许nan
函数在不影响值的情况下工作
def to_int(x):
try:
return int(x)
except:
return np.nan
df[column] = df[column].apply(to_int)
使用.fillna()
将所有NaN
值替换为0
,然后使用astype(int)
将其转换为int
对于任何需要在包含NULL/NaN的列中包含int值,但无法使用其他答案中提到的pandas版本0.24.0可为NULL的整数功能的人,我建议使用pd将列转换为对象类型。其中:
df = df.where(pd.notnull(df), None)
这会将dataframe中的所有NaN转换为None,将混合类型列视为对象,但将int值保留为int,而不是float。也有类似的问题。这就是我的解决方案:
def toint(zahl = 1.1):
try:
zahl = int(zahl)
except:
zahl = np.nan
return zahl
print(toint(4.776655), toint(np.nan), toint('test'))
4楠楠楠
首先需要指定较新的整数类型Int8(。
df['id'] = df['id'].fillna(0).astype(int)
df = df.where(pd.notnull(df), None)
def toint(zahl = 1.1):
try:
zahl = int(zahl)
except:
zahl = np.nan
return zahl
print(toint(4.776655), toint(np.nan), toint('test'))
df = pd.read_csv("data.csv")
df['id'] = df['id'].astype(float)
df['id'] = toint(df['id'])