【问题标题】:Python Pandas Lambda: Using multiple variables Lambda within DataFramePython Pandas Lambda:在 DataFrame 中使用多个变量 Lambda
【发布时间】:2017-01-02 22:23:46
【问题描述】:

我有一个系列,如下所示:

example = pd.Series([[1.0, 1209.75, 1207.25],
 [1.0, 1211.0, 1207.5],
 [-1.0, 1211.25, 1205.75],
 [0, 1207.25, 1206.0],
 [1.0, 1206.25, 1201.0],
 [-1.0, 1205.75, 1202.75],
 [0, 1205.5, 1203.75]])

这个系列基本上每个单元格中有 3 个数字的列表。 我把它变成一个 DataFrame 并添加一个新列:

example = example.to_frame(name="input")
example["result"]=np.NaN

现在我想对其执行以下操作:

example["result"] = example["input"].apply(lambda x,y,z: y if x==1 else z if x==-1 else NaN)

我在尝试执行此操作时收到以下错误消息: missing 2 required positional arguments: 'y' and 'z'

【问题讨论】:

    标签: python pandas lambda


    【解决方案1】:

    lambda 只接受一个参数,在这种情况下是一个列表。只需索引列表:

    >>> example["result"] = example["input"].apply(lambda lst: lst[1] if lst[0]==1 else lst[2] if lst[0]==-1 else np.NaN)
    >>> example
                          input   result
    0   [1.0, 1209.75, 1207.25]  1209.75
    1     [1.0, 1211.0, 1207.5]  1211.00
    2  [-1.0, 1211.25, 1205.75]  1205.75
    3      [0, 1207.25, 1206.0]      NaN
    4    [1.0, 1206.25, 1201.0]  1206.25
    5  [-1.0, 1205.75, 1202.75]  1202.75
    6      [0, 1205.5, 1203.75]      NaN
    

    简单来说,您可以将嵌套的三元运算符重构为带有嵌套 if 的函数,这样您的代码就更具可读性:

    def func(lst):
        x, y, z = lst
        if x == 1:
            return y
        elif x == -1:
            return z
        else:
            return np.NaN
    
    
    example["result"] = example["input"].apply(func)
    

    【讨论】:

    • 是的,我刚才也找到了……对不起,伙计们。但有趣的是,我的问题经常措辞足以让我找到答案......无论如何,谢谢!你的评论是什么意思?你有什么建议?
    • 非常感谢。在函数的情况下,为什么我们使用 x, y, z 而不是 lambda 中的 x[0], x[1], x[2]?函数和 lambda 不应该是等价的吗?
    • 我将lst 作为参数传递,而不是x。只是换个名字
    • 好吧,是的,我错过了那个。谢谢
    【解决方案2】:

    这是一个矢量化的解决方案:

    In [30]: example
    Out[30]:
                          input
    0   [1.0, 1209.75, 1207.25]
    1     [1.0, 1211.0, 1207.5]
    2  [-1.0, 1211.25, 1205.75]
    3      [0, 1207.25, 1206.0]
    4    [1.0, 1206.25, 1201.0]
    5  [-1.0, 1205.75, 1202.75]
    6      [0, 1205.5, 1203.75]
    
    In [31]: example['result'] = np.where(np.isclose(example.input.str[0], 1),
        ...:                              example.input.str[1],
        ...:                              np.where(np.isclose(example.input.str[0], -1),
        ...:                                       example.input.str[2],
        ...:                                       np.nan))
        ...:
    
    In [32]: example
    Out[32]:
                          input   result
    0   [1.0, 1209.75, 1207.25]  1209.75
    1     [1.0, 1211.0, 1207.5]  1211.00
    2  [-1.0, 1211.25, 1205.75]  1205.75
    3      [0, 1207.25, 1206.0]      NaN
    4    [1.0, 1206.25, 1201.0]  1206.25
    5  [-1.0, 1205.75, 1202.75]  1202.75
    6      [0, 1205.5, 1203.75]      NaN
    

    【讨论】:

    • 这不处理example.str[0]为-1的情况
    • @MaxU 这很有趣,除了 .isclose 有点不幸
    • @MosesKoledoye,感谢您指出!我已经更正了我的答案
    • @jimbasquiat,当使用float dtype 时,它​​是better to compare values using isclose or allclose
    猜你喜欢
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    相关资源
    最近更新 更多