为什么python lambda看到的是一个系列而不是一个值?
我创建一个数据帧:为什么python lambda看到的是一个系列而不是一个值?,python,python-3.x,pandas,lambda,Python,Python 3.x,Pandas,Lambda,我创建一个数据帧: df = pd.DataFrame( {'some_number' : [1,2,3,4,5,6]}) 然后我想添加一个名为is_偶数的列: df.assign( is_even = lambda x : 'YES' if x.some_number % 2 == 0 else 'NO' ) 我得到一个错误: ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(),
df = pd.DataFrame( {'some_number' : [1,2,3,4,5,6]})
然后我想添加一个名为is_偶数的列:
df.assign(
is_even = lambda x : 'YES' if x.some_number % 2 == 0 else 'NO'
)
我得到一个错误:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
我知道错误告诉我if语句后面的x.some_number
是一个序列。这让我很困惑,因为如果我这样做:
df.assign(
is_even = lambda x : 'YES' if 1==2 else x.some_number
)
它工作并生成以下输出:
这表明x.some_数实际上不是一个级数,而是一个标量值
我知道还有其他方法可以完成我想要完成的事情。但我对这种行为感兴趣
为什么,当x.some_数位于if
子句之后时,它被视为一个序列,但当它在else
子句中使用时,它被视为一个值
INSTALLED VERSIONS
------------------
python : 3.8.0.final.0
python-bits : 32
OS : Windows
OS-release : 10
machine : AMD64
processor : Intel64 Family 6 Model 158 Stepping 10, GenuineIntel
byteorder : little
LOCALE : English_United States.1252
pandas : 0.25.3
numpy : 1.17.4
IPython : 7.10.0
matplotlib : 3.1.2
问题仅在于if语句,在第一个示例中,您正在将一个序列与标量值进行比较。这是行不通的。第二个示例之所以有效,是因为您只有一个标量if语句(当然可以),然后返回一个序列。返回序列(或标量)正是传递给assign
的函数需要做的事情
现在,你真正想做的,是一个逐行比较。使用apply
进行此操作
df['is_偶数']=df.some_number.apply(λx:'YES'如果x%2==0,则为'NO')
这里,x是一个标量,if语句按预期工作。
或者,您可以将assign和lambda函数结合使用
df.assign(
is_偶数=λx:x.某个_数。应用(λx:如果x%2==0,则为“是”,否则为“否”)
)
请再次注意第一个示例的区别:如果x%2==0,则外部lambda确保内部lambda只需处理
中的标量。外部lambda返回一个序列,就像在第二个示例中一样。您的证明不成立。PandasDataframe.assign
似乎能够处理一个系列或标量,并将其应用于数据帧
[7]中的:df.assign(is_偶数=lambda x:x.some_编号[0])
出[7]:
有些数字是偶数
0 1 1
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1
如果阅读,您将看到该参数接受回调或序列,并应用它(依赖于类型)
列名是关键字。如果这些值是可调用的,则在数据帧上计算它们并将其分配给新列。可调用对象不能更改输入数据帧(尽管pandas不检查它)。如果值是不可调用的(例如,一个系列、标量或数组),则只需对其赋值
此外,如果您深入了解一下源代码:
#>=3.6维护kwargs的秩序
如果PY36:
对于k,v在kwargs.items()中:
数据[k]=com.apply\u如果可调用(v,数据)
您可以看到它是否是可调用的,它将整个数据帧传递给您的可调用