【问题标题】:How to substitute two columns with a condition in pandas?如何用熊猫中的条件替换两列?
【发布时间】:2020-04-21 00:52:08
【问题描述】:

我有一个包含产品、操作、数量和价格的 Pandas DataFrame。如果动作是“卖出”,我需要考虑产品的价格为 0 并反转数量。

我尝试过的:

import pandas as pd


def my_function(df):
    kwargs = {
        "quantity": lambda x: -x["quantity"] if "SELL" in str(x["action"]) else x["quantity"],
        "price (usd)": lambda x: 0 if "SELL" in str(x["action"]) else x["price (usd)"],
    }
    return df.assign(**kwargs)


input_df = pd.DataFrame({"product": ["APPLE", "APPLE", "BANANA"],
                         "action": ["  SELL  ", "  BUY  ", "  SELL  "],
                         "quantity": [1, 2, 3],
                         "price (usd)": [3, 5, 8],
                         })

result_df = my_function(input_df)

expected_df = pd.DataFrame({"product": ["APPLE", "APPLE", "BANANA"],
                            "action": ["  SELL  ", "  BUY  ", "  SELL  "],
                            "quantity": [-1, 2, -3],
                            "price (usd)": [0, 5, 0],
                            })

不知何故,我的 lambda 表达式中的条件总是返回 True,我也认为这可能是一种更简单的方法。有什么想法吗?

【问题讨论】:

    标签: python python-3.x pandas lambda


    【解决方案1】:

    我们可以的

    s=input_df.action.str.contains('SELL')
    input_df.quantity*=s.map({True:-1,False:1})
    input_df["price (usd)"]*=~s
    input_df
      product    action  quantity  price (usd)
    0   APPLE    SELL          -1            0
    1   APPLE     BUY           2            5
    2  BANANA    SELL          -3            0
    

    在函数中

    def my(x):
    ...     s=x.action.str.contains('SELL')
    ...     x.quantity*=s.map({True:-1,False:1})
    ...     x["price (usd)"]*=~s
    ...     return (x)
    
    
    out=my(input_df)
    out
      product    action  quantity  price (usd)
    0   APPLE    SELL          -1            0
    1   APPLE     BUY           2            5
    2  BANANA    SELL          -3            0
    

    【讨论】:

    • 我也会使用x["price (usd)"] *= sells.map({True: 0, False: 1}) 让代码更容易理解。
    【解决方案2】:

    下面的代码修复了它。我得到了想要的输出。

    def my_function(df):
        kwargs = {
            "quantity": df.apply(lambda x: -x["quantity"] if "SELL" in str(x["action"]) else x["quantity"], axis = 1),
            "price (usd)": df.apply(lambda x: 0 if "SELL" in str(x["action"]) else x["price (usd)"], axis = 1),
        }
        return df.assign(**kwargs)
    

    【讨论】:

    • 很好,这行得通。只是为了可读性,我使用axis =“columns”而不是axis = 1。谢谢拉明。这绝对可以被认为是一个答案,但我认为使用 Yoben 的程序更容易理解。
    • @staticdev 你没有要求不同的程序。你就你的代码寻求帮助。我帮你写了代码。关于“更容易理解”的事情,我不确定他的代码比你的代码更容易阅读。看到他的代码后,可读性是我关心的问题。事实上,我认为你的代码比他的更容易理解。
    猜你喜欢
    • 2017-11-30
    • 2022-08-11
    • 2013-04-15
    • 2021-12-20
    • 1970-01-01
    • 2019-05-29
    • 2021-05-20
    • 1970-01-01
    • 2020-04-19
    相关资源
    最近更新 更多