Python 如何将自定义百分比更改应用于数据帧?

Python 如何将自定义百分比更改应用于数据帧?,python,pandas,dataframe,apply,Python,Pandas,Dataframe,Apply,我希望对数据帧行应用自定义百分比,每个公司id的最后一行应始终为零。我尝试使用df.apply方法,但无法传递多个参数。如果你能告诉我这个问题有多少种解决方法,我将不胜感激?提前感谢您的关注和努力 df = pd.DataFrame({'CompanyId' : ['A','A','A','B','B'], 'stand_alone' : [10,12,-5,20,1]}) def get_change(c

我希望对数据帧行应用自定义百分比,每个公司id的最后一行应始终为零。我尝试使用df.apply方法,但无法传递多个参数。如果你能告诉我这个问题有多少种解决方法,我将不胜感激?提前感谢您的关注和努力

df = pd.DataFrame({'CompanyId' : ['A','A','A','B','B'],                           
                 'stand_alone' : [10,12,-5,20,1]})

def get_change(current,previous):
    if current==previous:
        return 0
    if current>=0 and previous<0:
        chg=1.0
    if current>=0 and previous==0:
        chg=1.0
    if current<0 and previous>0:
        chg=-1.0
    if current>0 and previous>0:
        chg=abs(current)/abs(previous)-1
    if current<0 and previous<0:
        chg=abs(current)/abs(previous)-1
        chg=-chg
    return round(chg*100,2)

好的,这里有一种方法可以用你现在的逻辑来做

def get_change(x):
    x=x.sort_index(ascending=False)
    cond1 = x == x.shift(1)
    result1 = 0
    cond2 = (x < 0) & x.shift(1) > 0
    result2 = -1
    cond3 = ((x>0) & (x.shift(1)>0)) | ((x<0) & (x.shift(1)<0))
    result3 = (x/x.shift(1)) - 1
    cond4 = ((x>=0)&(x.shift(1)<=0)) 
    result4 = 1
    result = np.select([cond1,cond2,cond3,cond4],[result1,result2,result3,result4])*100
    return result[::-1]

df['change'] = df.groupby('CompanyId')['stand_alone'].transform(get_change).round(2)
print(df)

我认为这种方法需要使用的关键功能是
np。选择
一种执行if-then-elseif逻辑的方法,然后选择
groupby
使用
transform

一种简单而直接的方法,将带有先前值的列添加为当前值的移位。 避免对行应用
,这是您最不可能做的事情,因为性能非常低(比对多行应用稍微有效)

df=df.assign(previous=df.groupby('CompanyId')。独立。移位(-1)
).assign(chg=np.NaN)
df.loc[(df.stand_-df.previous)=0)和(df.previous 0),'chg']=-1。
遮罩=(单独的df.stand_>0)和(df.previous>0)
df.loc[mask,'chg']=np.abs(df[mask]。独立/df[mask]。上一个)-1
掩码=(单独的df.stand_<0)和(df.previous=0和previous=0和previous=0:
chg=1.0
如果当前为0:
chg=-1.0
如果当前>0且以前>0:
chg=防抱死制动系统(当前)/防抱死制动系统(以前)-1

如果当前>0,而以前>0,为什么要使用abs?我可能会删除abs。您可以忽略它。我尚未完全开发我的功能
def get_change(x):
    x=x.sort_index(ascending=False)
    cond1 = x == x.shift(1)
    result1 = 0
    cond2 = (x < 0) & x.shift(1) > 0
    result2 = -1
    cond3 = ((x>0) & (x.shift(1)>0)) | ((x<0) & (x.shift(1)<0))
    result3 = (x/x.shift(1)) - 1
    cond4 = ((x>=0)&(x.shift(1)<=0)) 
    result4 = 1
    result = np.select([cond1,cond2,cond3,cond4],[result1,result2,result3,result4])*100
    return result[::-1]

df['change'] = df.groupby('CompanyId')['stand_alone'].transform(get_change).round(2)
print(df)
  CompanyId  stand_alone   change
0         A           10   -16.67
1         A           12   100.00
2         A           -5     0.00
3         B           20  1900.00
4         B            1     0.00