为什么使用 pandas dataframe 赋值时会出现 TypeError 错误?

3

环境:

Python 3.6.4
pandas 0.23.4

以下是我的代码。

from math import sqrt
import pandas as pd
df = pd.DataFrame({'x':[1,2,3], 'y':[4,5,6]})

df = df.assign(d = lambda z: sqrt(z.x**2 + z.y**2))

底线会引发如下类型错误。
...
TypeError: cannot convert the series to <class 'float'>

没有使用sqrt函数,它可以正常工作。
df = df.assign(d2 = lambda z: z.x**2 + z.y**2)
df
Out[6]:
   x  y  d2
0  1  4  17
1  2  5  29
2  3  6  45

同时,apply 也是有效的。

df['d3'] = df.apply(lambda z: sqrt(z.x**2 + z.y**2), axis=1)
df
Out[8]:
   x  y  d2        d3
0  1  4  17  4.123106
1  2  5  29  5.385165
2  3  6  45  6.708204

第一个有什么问题?
2个回答

2

使用numpy.sqrt - 它也适用于1d数组,而math中的sqrt仅适用于标量:


df = df.assign(d = lambda z: np.sqrt(z.x**2 + z.y**2))

另一个解决方案是使用**(1/2): "最初的回答"。
df = df.assign(d = lambda z: (z.x**2 + z.y**2)**(1/2))

print (df)
   x  y         d
0  1  4  4.123106
1  2  5  5.385165
2  3  6  6.708204

你的解决方案有效,因为在apply中,axis=1按标量工作,但正如@jpp所提到的,不应该优先使用apply,因为它涉及Python级别的逐行循环。"最初的回答"
df.apply(lambda z: print(z.x), axis=1)
1
2
3

非常感谢。pandas.apply是对每个值(标量)执行的,因此apply有效。在这种情况下,我不应该使用apply。 - rootpetit
1
@rootpetit - 没错,应用程序在这里并不必要,因为已存在矢量化的解决方案。 - jezrael

0

pandas系列对象就像numpy数组一样,无法操作寻找单个对象而不是系列的数学模块。 默认的数学运算是有效的,但不能处理数组/系列上不起作用的函数。

你可以做的是:

df = df.assign(d = lambda z: (z.x**0.5 + z.y**0.5))

或者

df['d'] = df.z.x**0.5 + df.y.x**0.5

这是在pandas标准操作中定义的。


谢谢你的答案和@jezwels的答案,我现在明白它为什么有效或者无效。 - rootpetit

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