python - 当有多个变量时使用lambda在python数据帧中实现if-else

标签 python python-3.x pandas if-statement lambda

我正在尝试在处理数据帧时在 python 中实现 if-elif 或 if-else 逻辑。使用多个列时,我很吃力。

示例数据框

df=pd.DataFrame({"one":[1,2,3,4,5],"two":[6,7,8,9,10], "name": 'a', 'b', 'a', 'b', 'c'})

如果我的 if-else 逻辑仅基于一列 - 我知道该怎么做。

df['one'] = df["one"].apply(lambda x: x*10 if x<2 else (x**2 if x<4 else x+10))

但我想根据“二”列的值修改“一”列 - 我觉得它会像这样 -

lambda x, y: x*100 if y>8 else (x*1 if y<8 else x**2)

但我不确定如何指定第二列。我试过这种方式,但显然这是不正确的

df['one'] = df["one"]["two"].apply(lambda x, y: x*100 if y>8 else (x*1 if y<8 else x**2))

问题 1 - 上述代码的正确语法是什么?

问题 2 - 如何使用 lambda 实现以下逻辑?

if df['name'].isin(['a','b'])  df['one'] = 100 else df['one'] = df['two']

如果我写 x.isin(['a','b']) 这样的东西,它就不会工作。

最佳答案

跨列应用

使用pd.DataFrame.apply而不是 pd.Series.apply并指定 axis=1:

df['one'] = df.apply(lambda row: row['one']*100 if row['two']>8 else \
                     (row['one']*1 if row['two']<8 else row['one']**2), axis=1)

不可读?是的我同意。让我们再试一次,但这次重写为命名函数。

使用函数

注意 lambda 只是一个匿名函数。我们可以显式定义一个函数并将其与 pd.DataFrame.apply 一起使用:

def calc(row):
    if row['two'] > 8:
        return row['one'] * 100
    elif row['two'] < 8:
        return row['one']
    else:
        return row['one']**2

df['one'] = df.apply(calc, axis=1)

可读?是的。但这不是矢量化的。我们一次循环遍历每一行。我们不妨使用一个列表。 Pandas 不仅用于巧妙的表格格式化,您还可以使用它在连续内存块中使用数组进行矢量化计算。那么让我们再试一次。

向量化计算

使用 numpy.where :

df['one'] = np.where(row['two'] > 8, row['one'] * 100,
                     np.where(row['two'] < 8, row['one'],
                              row['one']**2))

我们开始吧。可读并且高效。我们已经有效地向量化了我们的 if/else 语句。这是否意味着我们进行了不必要的计算?是的!但这不仅仅是我们执行计算的方式所抵消的,即使用定义明确的内存块而不是指针。您会发现性能提高了一个数量级。

另一个例子

好吧,我们可以再次使用 numpy.where

df['one'] = np.where(df['name'].isin(['a', 'b']), 100, df['two'])

关于python - 当有多个变量时使用lambda在python数据帧中实现if-else,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50730408/

相关文章:

BLE 的 python3 root 权限

python - 将 pandas 数据帧传递给 fastapi

python - 在 Python 中引发错误的一种非常优雅的方式是什么

python - pandas 中多索引数据帧的累积百分比

python - 从 shell 脚本中执行 python 代码

Python HTTPServer serve_forever 控制台输入

python - Pandas:将分类列分解为多列

python - 在将混合类型的列值与 pandas Dataframe 中的 int 或 float 进行比较时跳过字符串值

Python请求SSL错误-证书验证失败

python - SQLALchemy 动态 filter_by