Python Pandas:使用'apply'将1个函数应用于多个列

时间:2015-02-28 21:10:58

标签: python pandas

Quick Pandas DataFrame问题......只是一个概念性问题

假设我有一个3列的DataFrame。称之为df

     A    B    C
0    1    2    3
1    1    2    3
2    1    2    3
3    1    2    3
4    1    2    3

现在假设我有一个函数f(A,B,C),理论上我会将列ABC作为输入。例如,

 def function(A,B,C):
     return (A+1, B/2, C*3)

这个函数当然会返回一个元组。

基本上,我想知道我是否可以将function应用于df以获得以下输出:

     A    B    C
0    2    1    9
1    2    1    9
2    2    1    9
3    2    1    9
4    2    1    9

如果是这样,我该怎么做?我不能只输入df.apply(function)。我会得到一个类似于:

的TypeError

'function()' takes exactly 3 arguments (1 given)'

如果我不能这样做,我认为我必须创建个别功能?像...

def f1(A):
    return A+1

def f2(B):
    return B/2

def f3(C):
    return C*3

3 个答案:

答案 0 :(得分:1)

你可以这样做:

>>> pandas.concat(function(*[col for colname, col in df.iteritems()]), axis=1)
    A  B  C
0  2  1  9
1  2  1  9
2  2  1  9
3  2  1  9
4  2  1  9

如果你的函数按行运行(即,它接受三个单独的值A,B和C并返回三个输出的元组),那么你可以这样做:

>>> d.apply(lambda r: function(*r), axis=1)
    A  B  C
0  2  1  9
1  2  1  9
2  2  1  9
3  2  1  9
4  2  1  9

(你需要将它包装在一个lambda中,以便将每一行的元素作为单独的参数传递。)但是如果你的函数是可矢量化的,那么这是有效的,因为那时你想要立即对整个列进行操作,而不是而不是重做每一行的操作。

你说该函数返回"一个元组,当然",但是传递单独的列并返回它们的元组并不是操纵pandas数据结构的好方法。设置函数的方式,您希望将DataFrame分离为单独的列,将它们作为单独的参数传递,将单独的列作为元组检索,然后在最后将它们组合回DataFrame。但是已经有一个数据结构可以容纳多个列,即一个DataFrame。因此,如果您希望函数获取一些DataFrame列并返回一些DataFrame列,则应该让它接受一个DataFrame并返回一个DataFrame:

def function(df):
    return pandas.concat([df.A+1, df.B/2, df.C*3], axis=1)

(如果你不希望函数依赖于列名,你可以让它通过数字索引来访问列。)然后你可以直接在DataFrame上调用函数:

>>> function(d)
    A  B  C
0  2  1  9
1  2  1  9
2  2  1  9
3  2  1  9
4  2  1  9

当然,如果从其他地方获得该功能,您可能无法重写它,在这种情况下,您可以使用我之前提到的那种解决方案。

答案 1 :(得分:0)

您的问题分为两部分:轴和功能应用程序

  1. 您需要在每一行上应用该功能,为此您需要指定axis = 1

    df.apply(function, axis=1)
    

    否则,默认情况下,该功能将应用于每列。

    1. 包装功能
    2. 你需要传递一个带有一个参数的函数,该函数包含函数(我假设'函数'是一个已经存在的函数,例如来自库,你不能自己修改它)

      def functionwrap(row):
          return function(row[0], row[1], row[2])
      
      df.apply(functionwrap, axis=1)
      
      1. Lambda函数
      2. 更紧凑的是提供lambda功能。在这种情况下,它很有效,因为lambda非常简单。

        df.apply(lambda x: function(*x), axis=1)
        

        提醒一下,* x正在将行转换为函数调用中的参数列表,有效地调用函数(a,b,c)。这当然只适用于有3列的DataFrame,否则你会在这里得到一个例外(即你试图传递n个参数而不是3,其中n是你的DataFrame中的列数)。

答案 2 :(得分:0)

 df.A, df.B, df.C = function(df.A, df.B, df.C)
当你通过系列赛时,熊猫会做一些方便的事情。