从应用泛型函数(x,y)的两个现有列创建一个新列,以便我可以使用具有不同列的函数

问题描述 投票:2回答:4

我正在尝试计算一个折扣,我想将其应用于我的数据框的两列的每一行,并将结果添加到新列。

我已经尝试了许多方法,通过遵循现有的示例,但每次发生错误。

我将函数定义为:

def delta_perc(x,y):
    if y == 0:
        return 0
    else:
        return (x-y)/x*100

然后尝试将该函数应用于我的数据帧

ordini["discount"] = ordini.apply(delta_perc(ordini["revenue1"],ordini["revenue2"]), axis=1)

我期待一个新列,其中每一行都是应用于ordini [“revenue1”]和ordini [“revenue2”]的函数的结果。

但是我收到以下错误:

ValueError:Series的真值是不明确的。使用a.empty,a.bool(),a.item(),a.any()或a.all()。

我也尝试应用qazxsw poi的所有建议,但每次发生错误。

python-3.x pandas function dataframe apply
4个回答
3
投票

你得到了一些混乱的概念。当您使用here(使用pandas.DataFrame.apply)时,您将遍历每一行并将该行(作为axis=1对象)传递给您调用pandas.Series时使用的函数。

First Point of Failure

相反,您在apply中调用函数并将两列传递给函数。这会将函数的返回值传递给apply。由于您的函数没有传回一个可调用的对象,因此这应该失败。

Second Point of Failure

此外,你的函数被设计为查看标量值,因此apply,当你像if y == 0:(这是一个ordini["revenue1"]对象)传递列时,它试图评估pandas.Series,这就是产生你看到的错误的原因:

if pandas.Series == 0:

Approach #1

修复你的功能,不要使用ValueError: The truth value of a Series is ambiguous.

apply

Approach #2

修复你的功能并使用qazxsw poi。这与使用理解类似。

def delta_perc(x, y):
    return x.sub(y).div(x).mask(x == 0, 0).mul(100)

ordini["discount"] = delta_perc(ordini["revenue1"], ordini["revenue2"])

Approach #3

实际上使用map

def delta_perc(x, y):
    if x == 0:
        return 0
    else:
        return (x - y) / x * 100

ordini["discount"] = [*map(delta_perc, ordini["revenue1"], ordini["revenue2"])]

2
投票

你也可以尝试:

apply

2
投票

您应该使用def delta_perc(x, y): if x == 0: return 0 else: return (x - y) / x * 100 # Because remember `apply` takes a function that gets a row (or column) passed to it ordini["discount"] = ordini.apply( lambda row: delta_perc(row['revenue1'], row['revenue2']), axis=1 ) 将此计算应用于整个系列:

ordini["discount"] = [delta_perc(a,b) for a,b in zip(ordini["revenue1"],ordini["revenue2"])]

Example:

np.where

1
投票

你有没有尝试在import pandas as pd import numpy as np def delta_perc(x, y): return np.where(y != 0, (x-y)/x*100, 0) # I think you may want when x != 0, since you divide by x: #return np.where(x != 0, (x-y)/x*100, 0) 中加入np.random.seed(12) df = pd.DataFrame(np.random.randint(0,10,(10,2))) df['new_col'] = delta_perc(df[0], df[1]) # 0 1 new_col #0 6 1 83.333333 #1 2 3 -50.000000 #2 3 0 0.000000 #3 6 1 83.333333 #4 4 5 -25.000000 #5 9 2 77.777778 #6 6 0 0.000000 #7 5 8 -60.000000 #8 2 9 -350.000000 #9 3 4 -33.333333

lambda

如果性能对您很重要,请尝试这样做。

apply
© www.soinside.com 2019 - 2024. All rights reserved.