为什么在Pandas 2.x中更新列时数据类型不变,而在Pandas 1.x中会变化?

1 投票
1 回答
37 浏览
提问于 2025-04-14 17:33

在改变特定列的值或数据类型时,Pandas 1.x 和 2.x 的表现是不同的。

举个例子,下面的例子中关于列 e 的情况:

  • Pandas 1.x:使用 pd.to_datetime 来更新这一列时,会解析日期并改变它的数据类型。
  • Pandas 2.x:使用 pd.to_datetime 来更新这一列时,会解析日期,但不会改变它的数据类型。

从 Pandas 1.x 到 2.x 的变化是什么,导致了这种行为呢?

示例代码

import pandas as pd

# Creates example DataFrame
df = pd.DataFrame({
    'a': ['1', '2'],
    'b': ['1.0', '2.0'],
    'c': ['True', 'False'],
    'd': ['2024-03-07', '2024-03-06'],
    'e': ['07/03/2024', '06/03/2024'],
    'f': ['aa', 'bb'],
})

# Changes dtypes of existing columns
df.loc[:, 'a'] = df.a.astype('int')
df.loc[:, 'b'] = df.b.astype('float')
df.loc[:, 'c'] = df.c.astype('bool')

# Parses and changes dates dtypes
df.loc[:, 'd'] = pd.to_datetime(df.d)
df.loc[:, 'e'] = pd.to_datetime(df.e, format='%d/%m/%Y')

# Changes values of existing columns
df.loc[:, 'f'] = df.f + 'cc'

# Creates new column
df.loc[:, 'g'] = [1, 2]

Pandas 1.5.2 的结果

In [2]: df
Out[2]: 
   a    b     c          d          e     f  g
0  1  1.0  True 2024-03-07 2024-03-07  aacc  1
1  2  2.0  True 2024-03-06 2024-03-06  bbcc  2

In [3]: df.dtypes
Out[3]: 
a             int64
b           float64
c              bool
d    datetime64[ns]
e    datetime64[ns]
f            object
g             int64
dtype: object

Pandas 2.1.4 的结果

In [2]: df
Out[2]: 
   a    b     c                    d                    e     f  g
0  1  1.0  True  2024-03-07 00:00:00  2024-03-07 00:00:00  aacc  1
1  2  2.0  True  2024-03-06 00:00:00  2024-03-06 00:00:00  bbcc  2

In [3]: df.dtypes
Out[3]: 
a    object
b    object
c    object
d    object
e    object
f    object
g     int64
dtype: object

1 个回答

3

来自 Pandas 2.0.0的新特性(2023年4月3日)

在使用 df.loc[:, foo] = bardf.iloc[:, foo] = bar 设置值时,行为发生了变化,现在它们会优先尝试直接在原地设置值,如果失败才会进行类型转换(GH 45333)。

所以在Pandas 2及以上版本中,每当你用 .loc 设置值时,它会尝试直接在原来的地方修改。如果成功了,就不会新建一列,也会保留原有列的数据类型 dtype

对比一下 df[foo] = bar:这样会新建一列,数据类型会根据你设置的值来推断。比如,当你执行 df['d'] = pd.to_datetime(df.d) 时,即使在Pandas 2中,它也会新建一列,数据类型会是 datetime64[ns]

撰写回答