在pandas数据框中使用逐行应用时,如何保留数据类型?
问题内容:
我遇到一个奇怪的问题,其中apply
在数据帧上逐行使用函数不能保留数据帧中值的数据类型。有没有一种方法可以在保留原始数据类型的数据帧上逐行应用功能?
下面的代码演示了此问题。如果没有在下面int(...)
的format
函数中进行转换,则会出现错误,因为数据帧中的int在传递到时已转换为float
func
。
import pandas as pd
df = pd.DataFrame({'int_col': [1, 2], 'float_col': [1.23, 4.56]})
print(df)
print(df.dtypes)
def func(int_and_float):
int_val, float_val = int_and_float
print('int_val type:', type(int_val))
print('float_val type:', type(float_val))
return 'int-{:03d}_float-{:5.3f}'.format(int(int_val), float_val)
df['string_col'] = df[['int_col', 'float_col']].apply(func, axis=1)
print(df)
这是运行上述代码的输出:
float_col int_col
0 1.23 1
1 4.56 2
float_col float64
int_col int64
dtype: object
int_val type: <class 'numpy.float64'>
float_val type: <class 'numpy.float64'>
int_val type: <class 'numpy.float64'>
float_val type: <class 'numpy.float64'>
float_col int_col string_col
0 1.23 1 int-001_float-1.230
1 4.56 2 int-002_float-4.560
请注意,即使的int_col
列df
具有dtype int64
,但当该列中的值传递给function时func
,它们突然具有dtype
numpy.float64
,我必须int(...)
在函数的最后一行中使用以进行转换,否则该行将产生错误。
如有必要,我可以按照这里的方式处理此问题,但我真的很想了解为什么会看到这种意外行为。
问题答案:
您的整数越来越 upcasted
成浮动。如果可能,Pandas(和NumPy)将尝试将Series(或ndarray)制成单个数据类型。据我所知,没有详细记录向上转换的规则,但是您可以使用看到如何向上转换不同的类型numpy.find_common_type
。
您可以通过在调用apply之前将DataFrame强制转换为“ Object”类型来欺骗Pandas和NumPy保持原始数据类型,如下所示:
df['string_col'] = df[['int_col', 'float_col']].astype('O').apply(func, axis=1)
让我们分解一下这里发生的事情。首先,我们做完后df会发生什么.astype('O')
?
as_object = df[['int_col', 'float_col']].astype('O')
print(as_object.dtypes)
给出:
int_col object
float_col object
dtype: object
好的,现在两列都具有相同的dtype,即object。我们从之前知道apply()
(或者从DataFrame中提取一行的任何其他东西)都将尝试将两列转换为相同的dtype,但是它将看到它们已经相同,因此无需执行任何操作。
但是,我们仍然能够获得原始的整数和浮点数,因为它的dtype('O')
行为就像某种可以容纳任何python对象的容器类型。通常,当Series包含非混合类型(例如字符串和整数)或NumPy无法理解的任何python对象时,可以使用它。