Pandas - 使用 apply 为浮点数索引的数据框创建新列

3

我正在使用 pandas 13.0,尝试使用 apply() 和函数名 foo() 创建一个新的列。

我的数据框如下:

df = pandas.DataFrame({
         'a':[ 0.0,  0.1,  0.2,  0.3], 
         'b':[10.0, 20.0, 30.0, 40.0], 
         'c':[ 1.0,  2.0,  3.0,  4.0]
     })

df.set_index(df['a'], inplace=True)

我的数据框如下:
in: print df

out:
           a    b     c
      a
      0.0  0.0  10.0  1.0
      0.1  0.1  20.0  2.0
      0.2  0.2  30.0  3.0
      0.3  0.3  40.0  4.0 

我的函数如下所示:
def foo(arg1, arg2):
    return arg1*arg2

现在我想使用foo()创建一个名为“d”的列;
df['d'] = df.apply(foo(df['b'], df['c']), axis=1)

但是我遇到了以下错误:
TypeError: ("'Series' object is not callable", u'occurred at index 0.0')

如何在由浮点数组成的索引中使用pandas.apply()和foo()方法?

谢谢。

1个回答

5
这里的问题在于你试图逐行处理,但你传递了序列作为参数,这是错误的。你可以这样做:
In [7]:

df['d'] = df.apply(lambda row: foo(row['b'], row['c']), axis=1)
df
Out[7]:
       a   b  c    d
a                   
0.0  0.0  10  1   10
0.1  0.1  20  2   40
0.2  0.2  30  3   90
0.3  0.3  40  4  160

更好的方法是直接调用您的函数:
In [8]:

df['d'] = foo(df['b'], df['c'])
df
Out[8]:
       a   b  c    d
a                   
0.0  0.0  10  1   10
0.1  0.1  20  2   40
0.2  0.2  30  3   90
0.3  0.3  40  4  160

使用上述方法的优点是它是矢量化的,可以对整个系列执行操作,而不是逐行执行。
In [15]:

%timeit df['d'] = df.apply(lambda row: foo(row['b'], row['c']), axis=1)
%timeit df['d'] = foo(df['b'], df['c'])
1000 loops, best of 3: 270 µs per loop
1000 loops, best of 3: 214 µs per loop

这里并没有太大的差异,现在将其与一个有40万行的数据框进行比较:

In [18]:

%timeit df['d'] = df.apply(lambda row: foo(row['b'], row['c']), axis=1)
%timeit df['d'] = foo(df['b'], df['c'])
1 loops, best of 3: 5.84 s per loop
100 loops, best of 3: 8.68 ms per loop

所以你可以看到这里速度提高了约672倍。

非常感谢您的答复。现在它可以工作了。另外,速度比较也非常有用。再次感谢。 - Julien
没问题。一般来说,如果有向量化操作,请避免使用apply。对于基本的加/减/除和乘法运算,内置的运算符支持速度要快得多。 - EdChum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接