将包含 NaN 的 Pandas 列转换为 dtype `int`

2024-12-23 08:43:00
admin
原创
83
摘要:问题描述:我将数据从 .csv 文件读取到 Pandas 数据框中,如下所示。对于其中一列,即id,我想将列类型指定为int。问题是该id系列有缺失/空值。当我尝试id在读取 .csv 时将列转换为整数时,我得到:df= pd.read_csv("data.csv", dtype={'id...

问题描述:

我将数据从 .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

我该如何解决这个问题?


解决方案 1:

在 0.24.+ 版本中,pandas 已经获得了保存具有缺失值的整数数据类型的能力。

可空整数数据类型。

Pandas 可以使用 表示可能存在缺失值的整数数据arrays.IntegerArray。这是在 Pandas 中实现的扩展类型。它不是整​​数的默认数据类型,不会被推断;您必须明确将数据类型传递给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')

解决方案 2:

整数列中缺少 NaN 表示,这是Pandas 的一个“陷阱”。

通常的解决方法就是简单地使用浮点数。

解决方案 3:

我的用例是在将数据加载到数据库表之前对其进行处理:

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。

虽然它不漂亮,但是却能完成工作!

解决方案 4:

无论你的 pandas 系列是object数据类型还是简单的float数据类型,下面的方法都可以工作

df = pd.read_csv("data.csv") 
df['id'] = df['id'].astype(float).astype('Int64')

解决方案 5:

现在可以创建一个包含 NaN 作为 dtype 的 pandas 列int,因为它现在已在 pandas 0.24.0 上正式添加

pandas 0.24.x 发布说明
Quote: “ Pandas 已经能够保存具有缺失值的整数数据类型

解决方案 6:

从 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')

如果你确实有浮点数,那么可能必须使用圆形。

df['id'] = df['id'].round().astype('Int64')

文档在这里
https://pandas.pydata.org/pandas-docs/stable/user_guide/integer_na.html

解决方案 7:

几周前,我遇到了一些问题,这些问题涉及几个被格式化为“对象”的离散特征。这个解决方案似乎有效。

for col in discrete:
    df[col] = pd.to_numeric(df[col],errors='coerce').astype(pd.Int64Dtype())

解决方案 8:

如果您确实想在一列中组合整数和 NaN,则可以使用“对象”数据类型:

df['col'] = (
    df['col'].fillna(0)
    .astype(int)
    .astype(object)
    .where(df['col'].notnull())
)

这将用整数(无论哪个)替换 NaN,转换为 int,转换为对象,最后重新插入 NaN。

解决方案 9:

您可以使用.dropna()它可以删除具有 NaN 值的行。

df = df.dropna(subset=['id'])

或者,使用.fillna().astype()将 NaN 替换为值并将其转换为 int。

我在处理包含大整数的 CSV 文件时遇到了这个问题,其中有些整数缺失(NaN)。使用浮点型作为类型不是一个选择,因为我可能会丢失精度。

我的解决方案是使用 str 作为中间类型。然后您可以在代码中根据需要将字符串转换为 int。我用 0 替换了 NaN,但您可以选择任何值。

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

解决方案 10:

Int64与许多其他解决方案一样, 的问题在于,如果您有null值,它们将被替换为<NA>不适用于 pandas 默认“NaN”函数(如isnull()或 )的值fillna()。或者,如果您将值转换为-1,最终可能会删除您的信息。我的解决方案有点蹩脚,但会提供intnp.nan,让nan函数在不损害您的值的情况下工作。

            def to_int(x):
                try:
                    return int(x)
                except:
                    return np.nan

            df[column] = df[column].apply(to_int)

解决方案 11:

如果您可以修改存储的数据,请使用 sentinel value 来表示缺失值id。一个常见的用例,由列名推断,是id一个整数,严格大于零,您可以将其用作0sentinel value,以便您可以编写

if row['id']:
   regular_process(row)
else:
   special_process(row)

解决方案 12:

这里的大多数解决方案都告诉您如何使用占位符整数来表示空值。但是,如果您不确定整数不会出现在源数据中,则该方法无济于事。我的方法将格式化浮点数而不保留其小数,并将空值转换为 None。结果是一个对象数据类型,当加载到 CSV 中时,它将看起来像一个具有空值的整数字段。

keep_df[col] = keep_df[col].apply(lambda x: None if pandas.isnull(x) else '{0:.0f}'.format(pandas.to_numeric(x)))

解决方案 13:

对于需要在包含 NULL/NaN 的列中包含 int 值,但在无法使用其他答案中提到的 pandas 版本 0.24.0 可空整数功能的限制下工作的任何人,我建议使用 pd.where 将列转换为对象类型:

df = df.where(pd.notnull(df), None)

这会将数据框中的所有 NaN 转换为 None,将混合类型列视为对象,但将 int 值保留为 int,而不是浮点数。

解决方案 14:

如果你想在链接方法时使用它,你可以使用assign:

df = (
     df.assign(col = lambda x: x['col'].astype('Int64'))
)

解决方案 15:

首先,您需要指定较新的整数类型 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 cannot be converted to an IntegerDtype

df = df.astype(object)如果您不介意将每一列的数据类型更改为对象(单独地,每个值的类型仍然保留),
您可以这样做
...或者df = df.astype({"col1": object,"col2": object})如果您更喜欢针对单个列。

这应该有助于强制将混有空值的整数列保持为整数格式,并将空值更改为您喜欢的任何值。我无法评价这种方法的效率,但它对我的格式化和打印目的很有效。

解决方案 16:

我在使用 pyspark 时遇到了这个问题。由于这是在 jvm 上运行代码的 python 前端,因此它需要类型安全,并且不能使用 float 而不是 int。我通过将 pandas 包装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

解决方案 17:

import pandas as pd

df= pd.read_csv("data.csv")
df['id'] = pd.to_numeric(df['id'])

解决方案 18:

尝试一下:

df[['id']] = df[['id']].astype(pd.Int64Dtype())

如果你打印它 dtypes,你将得到 id Int64而不是正常的 one int64

解决方案 19:

df['id'] = df['id'].astype('float').astype(pd.Int64Dtype())

解决方案 20:

首先删除包含 NaN 的行。然后对剩余的行进行整数转换。最后再次插入删除的行。希望它能起作用

解决方案 21:

使用.fillna()替换所有NaN0然后将其转换为int使用astype(int)

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

解决方案 22:

遇到了类似的问题。这是我的解决方案:

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'])

解决方案 23:

由于我在这里没有看到答案,所以我不妨添加它:

如果你出于某种原因在依赖旧版本 pandas 的库时仍然无法处理 np.na 或 pd.NA ,则可以使用一行代码将 NAN 转换为空字符串:

df.select_dtypes('number').fillna(-1).astype(str).replace('-1', '')

解决方案 24:

我认为@Digestible1010101的方法更适合 Pandas 1.2.+ 版本,类似这样的方法应该可以完成工作:

df = df.astype({
            'col_1': 'Int64',
            'col_2': 'Int64',
            'col_3': 'Int64',
            'col_4': 'Int64', })

解决方案 25:

与@hibernado 的答案类似,但将其保留为整数(而不是字符串)

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

解决方案 26:

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

解决方案 27:

我使用以下解决方法:

condition = (~df['mixed_column'].isnull())
df['mixed_column'] = df['mixed_column'].mask(condition, df[condition]['mixed_column'].astype(int))

解决方案 28:

假设您不需要除相等之外的任何整数运算,则文件读取时的一种解决方法是不推断 dtype 并将所有内容导入为字符串。这效率较低,但简单且更接近 CSV 文件中的实际情况,因为 CSV 文件没有任何类型概念。

pd.read_csv(path, dtype=False)  

解决方案 29:

您可以尝试:

df.id = df.id.astype(int, errors = 'ignore')

除了int之外,还可以使用任何数字类型。

解决方案 30:

假设您的 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'))
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1120  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   75  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   66  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   76  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   70  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用