我将数据从.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
我该如何解决这个问题?
我在使用pyspark时遇到了这个问题。由于这是运行在jvm上的代码的python前端,它需要类型安全,使用float而不是int是不可取的。我把熊猫包裹起来,解决了这个问题。函数中的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
如果可以删除带有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
在0.24版本中。+ pandas获得了保存缺少值的整型dtypes的能力。
可空整数数据类型。
Pandas可以使用arrays.IntegerArray表示可能缺少值的整数数据。这是在pandas中实现的扩展类型。它不是整数的默认dtype,也不会被推断出来;你必须显式地将dtype传递给array()或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')
从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('Int64')
文件在这里
https://pandas.pydata.org/pandas-docs/stable/user_guide/integer_na.html
首先,您需要指定新的整数类型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值的整数列保持为整数格式,并将空值更改为您喜欢的任何值。我不能说这种方法的效率,但它适用于我的格式化和打印目的。