我想控制行上 apply 的输出数据类型。下面的foo和bar有多个输出。
import pandas as pd
def foo(x):
return x['a'] * x['b'], None, x['a'] > x['b']
def bar(x):
return x['a'] * x['b'], None
df = pd.DataFrame([{'a': 10, 'b': 2}, {'a': 10, 'b': 20}])
df2 = df.copy()
df[['product', 'dummy', 'greater']] = df.apply(foo, axis=1, result_type='expand')
df2[['product', 'dummy']] = df2.apply(bar, axis=1, result_type='expand')
输出数据类型为: |上校 | df | df2 | |-----|----|-----| |一个 | int64 | int64 | |乙| int64 | int64 | |产品 | int64 | float64 | |假人 | 对象 | float64 | |更大|布尔 | - |
对此问题的评论pandas apply改变dtype,表明apply返回具有单个dtype的系列。 bar 可能就是这种情况,因为输出可以转换为浮动。但 foo 的情况似乎并非如此,因为那样输出就需要是对象。
是否可以控制apply的输出数据类型? IE。获取/指定 bar 的输出 dtypes (int, object),还是我需要在最后强制转换 dtype?
熊猫版本1.5.2
IIUC,您问为什么
product
和 dummy
在应用 foo
和 bar
后具有不同的 dtype,即使这些函数返回的值对于这些新列是相同的?
col df df2
0 a int64 int64
1 b int64 int64
2 product int64 float64 # int64 <> float64
3 dummy object float64 # object <> float64
4 greater bool
如果是这样,那是因为当
result_type == "expand"
时,在幕后用 infer_to_same_shape
完成了特定的转换,大致相当于这个:
_datafoo = {0: (20, None, True), 1: (200, None, False)}
_databar = {0: (20, None), 1: (200, None)}
expandfoo = pd.DataFrame(_datafoo).T.set_axis(df.index).infer_objects()
expandbar = pd.DataFrame(_databar).T.set_axis(df.index).infer_objects()
输出(foo):
print(expandfoo.T, expandfoo, expandfoo.dtypes.to_dict(), sep="\n"*2)
0 1
0 20 200
1 None None
2 True False
0 1 2
0 20 None True
1 200 None False
{0: dtype('int64'), 1: dtype('O'), 2: dtype('bool')}
输出(条):
print(expandbar.T, expandbar, expandbar.dtypes.to_dict(), sep="\n"*2)
A B
0 20.0 200.0
1 NaN NaN # <-- see the presence of NaN
0 1
0 20.0 NaN
1 200.0 NaN
{0: dtype('float64'), 1: dtype('float64')}
infer_objects
都会将 expandbar
推断为 float64
(如果这不直观,请参阅 GH28318)。
是否可以控制
的输出数据类型?apply
这取决于应用函数的计算和返回的值。所以是的,您以某种方式拥有这种控制权,但您始终可以在末尾添加
convert_dtypes
或 astype
。