Pandas - 使用apply为浮点索引数据框创建新列
我正在使用 pandas 13.0,想通过 apply() 方法和一个叫 foo() 的函数来创建一个新列。
我的数据框(dataframe)如下:
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倍。