Pandas DataFrame.Apply输出格式

问题描述 投票:2回答:2

对python apply()pandas.DataFrame方法的输出有疑问

Q1 -

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 

Q2 -

出于某种原因,我想输出一个pandaq.Series数组:

0   [min(a)/2, max(a)/2]  
1   [min(b)/2, max(b)/2]
...

我尝试过reduce=True没有成功。然后,我该怎么办?

先感谢您。

python pandas dataframe apply
2个回答
1
投票

我更愿意避免在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允许您通过列表分配。


1
投票

因为结果数组的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

希望能帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.