Pandas DataFrame的立方根

时间:2017-06-08 14:33:54

标签: python python-3.x pandas numpy dataframe

我理解如何采用正数和负数的立方根。但是,当尝试使用apply - lambda方法有效地处理数据帧的所有元素时,我遇到了一个模糊问题。有趣的是,这个错误不会出现同等性,所以我想知道代码可能有什么问题:

sample[columns]=sample[columns].apply(lambda x: (-1)*np.power(-x,1./3) if x<0 else np.power(x,1./3))

3 个答案:

答案 0 :(得分:4)

看起来您正在传递列名或列名数组。我假设这是因为你的变量名是复数,最后是s。如果是这种情况,则sample[columns]是一个数据框。这是一个问题,因为apply会遍历每一列,并将您传递给lambda的{​​{1}}列传递给apply。所以你得到了

(-1) * np.power(-series_object, -1./3) if series_object < 0 else...

series_object < 0正在弄乱事情,因为你要求整个系列的真实性小于零。

applymap

f = lambda x: -np.power(-x, 1./3) if x < 0 else np.power(x, 1./3)
sample[columns] = sample[columns].applymap(f)

那就是说,我使用lambda定义如下

f = lambda x: np.sign(x) * np.power(abs(x), 1./3)

然后你可以在整个数据框上执行此操作

np.random.seed([3,1415])
df = pd.DataFrame(np.random.randint(-10, 10, (5, 5)))

df

    0  1   2  3   4
0   6  1  -8  0   5
1   3  1   3  9  -2
2 -10  2 -10 -8 -10
3  -3  9   3  8   2
4  -6 -7   9  3  -3
f = lambda x: np.sign(x) * np.power(abs(x), 1./3)
f(df)

          0         1         2         3         4
0  1.817121  1.000000 -2.000000  0.000000  1.709976
1  1.442250  1.000000  1.442250  2.080084 -1.259921
2 -2.154435  1.259921 -2.154435 -2.000000 -2.154435
3 -1.442250  2.080084  1.442250  2.000000  1.259921
4 -1.817121 -1.912931  2.080084  1.442250 -1.442250

相同
df.applymap(f)

          0         1         2         3         4
0  1.817121  1.000000 -2.000000  0.000000  1.709976
1  1.442250  1.000000  1.442250  2.080084 -1.259921
2 -2.154435  1.259921 -2.154435 -2.000000 -2.154435
3 -1.442250  2.080084  1.442250  2.000000  1.259921
4 -1.817121 -1.912931  2.080084  1.442250 -1.442250

检查是否相等

df.applymap(f).equals(f(df))

True

它更快

%timeit df.applymap(f)
%timeit f(df)

1000 loops, best of 3: 1.11 ms per loop
1000 loops, best of 3: 473 µs per loop

答案 1 :(得分:2)

它不必复杂,只需使用NumPys立方根函数:np.cbrt

df[columns] = np.cbrt(df[columns])

但它需要NumPy >= 1.10

对于旧版本,您可以使用np.absolutenp.sign代替使用条件:

df[columns] = df[columns].apply(lambda x: np.power(np.absolute(x), 1./3) * np.sign(x))

这会计算绝对值的立方根,然后适当地改变符号。

答案 2 :(得分:0)

尝试:

sample[columns]=sample[columns]**(1/3)