Skip to main content
 首页 » 编程设计

python之Pandas:基于多个其他列创建一个列。申请失败()

2025年05月04日10jyk

我有一个包含多列的数据框。我想为每一行分配一个优先级。 该优先级将根据其他列中的数据给出。

我定义了一个优先级函数

def priority(Bcat,Brand,IPC,Customer, Type): 
    p=1 
    if Bcat != "*": 
        p+= len(Bcat)/3 
    if Brand != "*": 
        p+= 2 
    if IPC != "*": 
        p+= 4 
    if Customer != "*" & Customer != "REPLCUST": 
        p+= 8 
    if Type == "Default": 
        p+= -16 
    return p 

现在我想将它应用于我的数据框。

这是我的数据框的样子(2500 行):

Bcat Brand Customer   IPC   LOC MKT_BUD      Type   STARTEFF    Value 
A    B     C          D      E   F            1     2001-01-01    1.0 

我正在尝试这个,但它不起作用

df["Priority"] = df[["Bcat","Brand","IPC","Customer","Type"]].apply(priority,axis=1,args=("Bcat","Brand","IPC","Customer","Type")) 

我收到这条消息

TypeError: ('priority() takes 5 positional arguments but 6 were given', 'occurred at index 0') 

也试过了

df["Priority"] = np.vectorize(priority(df.Bcat,df.Brand,df.IPC,df.Customer,df.Type)) 

收到这条消息

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all(). 

请您参考如下方法:

如果你想在你的数据框上使用应用程序,你可能需要一个 lambda 函数:

def priority(Bcat,Brand,IPC,Customer, Type): 
    p=1 
    if Bcat != "*": 
        p+= len(Bcat)/3 
    if Brand != "*": 
        p+= 2 
    if IPC != "*": 
        p+= 4 
    if (Customer != "*") & (Customer != "REPLCUST"): # Here you need brackets 
        p+= 8 
    if Type == "Default": 
        p+= -16 
    return p 
 
df= pd.DataFrame([['A','B','C','D','E','F','1','2001-01-01','1.0']],\ 
     columns = ['Bcat','Brand','Customer','IPC','LOC','MKT_BUD','Type','STARTEFF','Value']) 
 
df.apply(lambda x: priority(x.Bcat,x.Brand,x.IPC,x.Customer,x.Type),axis = 1) 
 
0    15.333333 
dtype: float64 

这将适用于数据帧,因此它可能不是最优的,因为它遍历行以访问 df.BCat 中字符串的长度。我会寻找更有效的方法。

编辑:

否则,您可以使用 str.len 来执行按列操作:

df['priority'] = 1 
mask = df.Bcat != "*" 
df.loc[mask,'priority'] += df.loc[mask,'Bcat'].str.len()/3 
df.loc[df.Brand != "*",'priority'] += 2 
df.loc[df.IPC != "*",'priority'] += 4 
df.loc[~df.Customer.isin(['*','REPLCUST']),'priority'] += 8 
df.loc[df.Type == "Default",'priority'] -= 16 
 
    Bcat    Brand   Customer    IPC LOC MKT_BUD Type  STARTEFF    Value priority 
0   A       B       C           D   E   F       1     2001-01-01  1.0   15.333333 

当您处理 Series 而不是遍历行时,这会更快。