当我们通过自定义函数对groupby的结果应用apply时,未传递所有列

时间:2018-12-10 02:05:05

标签: python pandas apply pandas-groupby

创建一个DataFrame,

x_df = pd.DataFrame({'a': [1,2,3,4,5,6], 'b': [1,2,1,2,1,2],
                     'c': ['x','x','y','y','z','z']})

Out[56]: 
   a  b  c
0  1  1  x
1  2  2  x
2  3  1  y
3  4  2  y
4  5  1  z
5  6  2  z

现在,我想对列'c'的每个值使用一个函数。因此,我对apply()的结果使用了groupby函数。

x_df = pd.DataFrame({'a': [1,2,3,4,5,6], 'b': [1,2,1,2,1,2], 'c': ['x','x','y','y','z','z']})

def fun(X):
    print("===============>>>>>>>>>>>>>>>>>>>>> ")
    print(list(X))
    print("\n")
    c_str = X.c.tolist[0]
    print("Value of c_str ==========>>> "+ str(c_str))
    return y


x_df1 = x_df.groupby('c').apply(fun).reset_index()

运行上面的代码将给出以下输出:

---------------------------------------------------------------
===============>>>>>>>>>>>>>>>>>>>>> 
['a', 'b', 'c']


===============>>>>>>>>>>>>>>>>>>>>> 
['a', 'b', 'c']


===============>>>>>>>>>>>>>>>>>>>>> 
**['a', 'b']**


===============>>>>>>>>>>>>>>>>>>>>> 
**['a', 'b']**


Traceback (most recent call last):

  File "<ipython-input-20-6870c2554589>", line 12, in <module>
    x_df1 = x_df.groupby('c').apply(fun).reset_index()

  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 930, in apply
    return self._python_apply_general(f)

  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 936, in _python_apply_general
    self.axis)

  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 2273, in apply
    res = f(group)

  File "<ipython-input-20-6870c2554589>", line 6, in fun
    c_str = X.c.tolist[0]

  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\generic.py", line 4376, in __getattr__
    return object.__getattribute__(self, name)

AttributeError: 'DataFrame' object has no attribute 'c'

因此,函数fun X的前两个调用具有所有三列(应该是这种情况),但是在第3和第4个调用列c中却缺少。因此,我无法访问它。有人可以指导我我做错了什么,为什么在第3和第4个通话中没有出现列c

2 个答案:

答案 0 :(得分:1)

问题在这里:

fiscal_months = [4,5,6,7,8,9,10,11,12,1,2,3]
index = [@month-3, 1].max
annual_taxable_income += total_monthly_income_present_month + @basic_salary * fiscal_months[index, 12].size

pd.Series.tolist是一种方法。要使用括号来调用方法:

c_str = X.c.tolist[0]

当然,还要确保定义c_str = X.c.tolist()[0]

答案 1 :(得分:1)

我会尽力回答您的问题,但首先我发现您的帖子有一些问题,所以我想指出它们:

  1. 您的格式被弄乱了,很难阅读代码。
  2. 您的fun函数未定义您要返回的变量:y
  3. 您的问题并未解释最初的问题是什么。您在问代码错误是什么,而不是解决问题的正确方法。

根据您的问题,您想对C中的每一行使用apply函数,但是按c分组可能会删除一些行。因此,您可以尝试

def fun(X):
    return X.c.tolist()[0]

x_df1 = x_df['c'].apply(fun)

但是可以更好地解决问题。除了传递分组的对象,您还可以传递列向量:

x_df1 = x_df['c'].apply(fun)

但是,如果我们知道您要解决的最初问题,那么我建议您申请一次lambda调用:

x_df1 = x_df['c'].apply(lambda x: list(x))

我使用了list(),但是应该替换为您尝试执行的操作。