我将数据从.csv文件读取到Pandas数据框架,如下所示。对于其中一列,即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

我该如何解决这个问题?


当前回答

df.loc[~df['id'].isna(), 'id'] = df.loc[~df['id'].isna(), 'id'].astype('int')

其他回答

首先,您需要指定新的整数类型Int8(…Int64),它可以处理空整数数据(pandas版本>= 0.24.0)

df = df.astype('Int8')

但是你可能想要只针对包含NaN/null的整数数据的特定列:

df = df . astype((’col1’:’Int8’’col2’:’Int8’、’col3’:’Int8’)

此时,NaN将被转换为<NA>,如果您希望使用df.fillna()更改默认空值,则需要在希望更改的列上强制使用对象数据类型,否则您将看到 TypeError: <U1不能转换为IntegerDtype

你可以通过 Df = Df .astype(对象)如果你不介意将每个列的数据类型更改为对象(单独地,每个值的类型仍然保留)…或 Df = Df。如果您喜欢针对单个列,则Astype ({"col1":对象,"col2":对象})。

这应该有助于强制将混合了null值的整数列保持为整数格式,并将空值更改为您喜欢的任何值。我不能说这种方法的效率,但它适用于我的格式化和打印目的。

类似于@hibernado的答案,但保持为整数(而不是字符串)

df[col] = df[col].fillna(-1)
df[col] = df[col].astype(int)
df[col] = np.where(df[col] == -1, np.nan, df[col])

假设您的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'))

如果可以删除带有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

使用.fillna()将所有NaN值替换为0,然后使用astype(int)将其转换为int

df['id'] = df['id'].fillna(0).astype(int)