对python apply()
中pandas.DataFrame
方法的输出有疑问
当pandas.DataFrame
函数返回与输入形状相同的pandas.DataFrame
时,为什么此函数返回与输入(apply
)格式相同的array
?
例如
foo = pd.DataFrame([[1,2],[3,4]],columns=['a','b'])
foo.apply(lambda x: [np.min(x)/2,np.max(x)/2], axis='index')
代码将返回:
a b
0 min(a)/2 min(b)/2
1 max(a)/2 max(b)/2
出于某种原因,我想输出一个pandaq.Series
数组:
0 [min(a)/2, max(a)/2]
1 [min(b)/2, max(b)/2]
...
我尝试过reduce=True
没有成功。然后,我该怎么办?
先感谢您。
我更愿意避免在apply
操作可能的numpy
。
在这种情况下,至少有几种选择。以下是基准测试的示例。如您所见,越接近numpy
,结果越好。
import pandas as pd, numpy as np
foo = pd.DataFrame([[1,2],[3,4]],columns=['a','b'])
foo = pd.concat([foo]*10000, ignore_index=True)
def dark(df):
return df.apply(lambda x: tuple([np.min(x)/2,np.max(x)/2]), axis=1)
def jp1(df):
return [tuple([np.min(x)/2,np.max(x)/2]) for x in foo[['a', 'b']].values]
def jp2(df):
arr = foo[['a', 'b']].values
return list(zip(*(np.min(arr, axis=1)/2, np.max(arr, axis=1)/2)))
%timeit dark(foo) # 4.95s
%timeit jp1(foo) # 298ms
%timeit jp2(foo) # 4.68ms
当然,dark()
返回pd.Series
,但pandas
允许您通过列表分配。
因为结果数组的ndim是2.如果你看到apply
here的主代码,如果ndim是2那么应用DataFrame构造函数。
#Main Code
...
# TODO: mixed type case
if result.ndim == 2:
return DataFrame(result, index=self.index, columns=self.columns)
else:
return Series(result, index=self._get_agg_axis(axis))
如果你想把结果作为序列,那么使用像tuple
而不是列表的东西,即
foo = pd.DataFrame([[1,2],[3,4]],columns=['a','b'])
foo.apply(lambda x: tuple([np.min(x)/2,np.max(x)/2]), axis=1)
输出:
0 (0.5, 1.0)
1 (1.5, 2.0)
dtype: object
希望能帮助到你。