使 Int64 成为默认的整数 dtype,而不是 pandas 中的标准 int64

Posted

技术标签:

【中文标题】使 Int64 成为默认的整数 dtype,而不是 pandas 中的标准 int64【英文标题】:Making Int64 the default integer dtype instead of standard int64 in pandas 【发布时间】:2019-10-06 19:22:08 【问题描述】:

我希望我的所有数据帧,无论它们是从任何一个构造函数重载构建的,无论它们是从 .read_csv().read_xlsx().read_sql() 还是任何其他方法派生的,使用新的可空 Int64 datatype 作为所有整数的默认 dtype,而不是 int64

如果没有“好”的方法,包括继承 DataFrame 或 Series 类,以及重新实现任意数量的方法和构造函数属性等,我愿意不顾一切地去做这件事。

我的问题是,可以做到吗?如果可以,我会怎么做?

【问题讨论】:

“我愿意到任何程度的精神错乱来做这件事”到那时,一切皆有可能。 这不是那么简单(显然),但你不能只写几行来将你可能需要的任何 int 列转换为可为空的吗? 【参考方案1】:

你可以使用这样的函数:

def nan_ints(df,convert_strings=False,subset = None):
    types = ['int64','float64']
    if subset is None:
        subset = list(df)
    if convert_strings:
        types.append('object')
    for col in subset:
        try:
            if df[col].dtype in types:
                df[col] = df[col].astype(float).astype('Int64')
        except:
            pass
    return df

它遍历每一列,如果它是 int,则将其转换为 Int64。如果它是浮点数,则只有当列中的所有值都可以转换为 NaN 以外的整数时,它才会转换为 Int64。我已经为您提供了将字符串转换为 Int64 的选项以及 convert_strings 参数。

df1 = pd.DataFrame('a':[1.1,2,3,1],
                  'b':[1,2,3,np.nan],
                  'c':['1','2','3',np.nan],
                  'd':[3,2,1,np.nan])


nan_ints(df1,convert_strings=True,subset=['b','c'])
df1.info()

将返回以下内容:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 4 columns):
a    4 non-null float64
b    3 non-null Int64
c    3 non-null Int64
d    3 non-null float64
dtypes: Int64(2), float64(2)
memory usage: 216.0 bytes

如果你打算在每个 DataFrame 上使用它,你可以将函数添加到模块中,并在每次你想使用 pandas 时导入它。 from my_module import nan_ints 然后只需将其与以下内容一起使用: nan_ints(pd.read_csv(path))

注意:可空整型数据类型是 0.24.0 版中的新增功能。 这是documentation。

【讨论】:

这会截断可能不希望出现的浮动(我认为通常不希望出现)... 如果列中的所有浮点数都是整数,它只会截断浮点列。对我来说似乎风险很低......我想我们可以添加一个可选参数来接受要转换的列列表。 @Any Hayden 我应该做那个编辑吗? @AndyHayden 我按要求添加了该列。 MatthewGdV 我是在正确的轨道上还是你完全想要别的东西? 我开始赏金是因为我希望找到一种方法来猴子补丁熊猫自动将 Int64 用于整数列,但同时我已经编写了类似的代码来将列转换为 Int64。 你为什么在.astype('Int64')之前调用.astype(float)【参考方案2】:

我会把钱花在猴子修补上。最简单的方法是修改 DataFrame 构造函数。应该是这样的:

import pandas
pandas.DataFrame.__old__init__ = pandas.DataFrame.__init__
def new_init(self, data=None, index=None, columns=None, dtype=pd.Int64Dtype(), copy=False):
    self.__old__init__(data=data, index=index, columns=None, dtype=dtype, copy=copy)

pandas.DataFrame.__init__ = new_init

当然,你冒着打破世界的风险。祝你好运!

【讨论】:

pd.DataFrame 构造函数为每列推断dtype(如果未指定)。此解决方案将强制所有调用者显式传递 dtype=None 以模拟该行为,这可能会破坏库中的许多内置函数。 是的,这就是我要打破世界的意思。这是一种尝试并查看解决方案。这将取决于他们如何使用图书馆。如果他们使用的所有数据都是整数数据,它可能会起作用。 我希望有一种方法可以对 pandas 进行猴子补丁,但我的列是不同类型的混合,所以我需要比这更复杂的东西。 啊,很公平。我不知道如何在不进入熊猫机器的情况下进行修补。我敢打赌,您可以进行更深层次的修补,但这需要进行大量调查,并且可能依赖于内部 API。

以上是关于使 Int64 成为默认的整数 dtype,而不是 pandas 中的标准 int64的主要内容,如果未能解决你的问题,请参考以下文章

将 pandas 系列的 dtype <- 'datetime64' 转换为 dtype <- 'np.int' 而无需迭代

numpy 数组 dtype 在 Windows 10 64 位机器中默认为 int32

为啥 object dtype 数组包含 datetime.datetime 对象而不是 numpy.datetime64 对象?

关键错误:[Int64Index...] dtype='int64] 均不在列中

php 使Elementor成为默认编辑器,而不是WordPress编辑器(Gutenberg或Classic)

php 使Elementor成为默认编辑器,而不是WordPress编辑器(Gutenberg或Classic)