我理解如何采用正数和负数的立方根。但是,当尝试使用apply
- lambda
方法有效地处理数据帧的所有元素时,我遇到了一个模糊问题。有趣的是,这个错误不会出现同等性,所以我想知道代码可能有什么问题:
sample[columns]=sample[columns].apply(lambda x: (-1)*np.power(-x,1./3) if x<0 else np.power(x,1./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.absolute
和np.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)