Pandas DataFrame.Apply输出格式

时间:2017-09-11 15:09:03

标签: python pandas dataframe apply

对python apply()

pandas.DataFrame方法的输出有疑问

Q1 -

为什么当pandas.DataFrame函数返回pandas.DataFrame时,此函数会返回与输入(apply)格式相同的<{1}} 与输入相同的形状?

例如

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') 

Q2 -

出于某种原因,我想输出一个 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] ... 但没有成功。 然后,我该怎么办?

提前谢谢。

2 个答案:

答案 0 :(得分: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

希望它有所帮助。

答案 1 :(得分: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会让您通过列表进行分配。