如何将不同的行的值分配给新列

时间:2019-01-02 22:49:55

标签: python pandas dataframe

我正在尝试将一列“ C_End”添加到Pandas中的DataFrame中,如下所示:

df = pd.DataFrame({'ID':[123,123,123,456,456,789],
                   'C_ID':[8,10,35,36,40,7],
                   'C_Type':['New','Renew','Renew','New','Term','New'],
                   'Rank':[1,2,3,1,2,1]})

对于基于“排名”的每个ID,新列都必须是下一个“ C_Type”,从而产生一个如下所示的DataFrame:

    ID  C_ID C_Type Rank  C_End  
0  123     8    New    1  Renew
1  123    10  Renew    2  Renew
2  123    35  Renew    3   None
3  456    36    New    1   Term
4  456    40   Term    2   None
5  789     7    New    1   None

基本上,我想找到ID = ID和Rank = Rank + 1的行,并将C_Type分配给新列C_End。我尝试过创建一个函数并使用Apply(在下面),但这花了很长时间,最终给了我一个错误。一般来说,我仍然对Pandas和Python还是陌生的,但是我觉得必须有一个我没有看到的简单解决方案。

def get_next_c_type(row):
    return df.loc[(df['id'] == row['id']) & (df['rank'] == row['rank'] + 1),'c_type']

df['c_end'] = df.apply(get_next_c_type, axis = 1)  

2 个答案:

答案 0 :(得分:3)

尝试:

df['C_End'] = df.sort_values('Rank').groupby('ID')['C_Type'].transform('shift',-1)

或如@ W-B建议:

df['C_End'] = df.sort_values('Rank').groupby('ID')['C_Type'].shift(-1)

输出:

    ID  C_ID C_Type  Rank  C_End
0  123     8    New     1  Renew
1  123    10  Renew     2  Renew
2  123    35  Renew     3    NaN
3  456    36    New     1   Term
4  456    40   Term     2    NaN
5  789     7    New     1    NaN

答案 1 :(得分:1)

这是使用np.where的一种方法:

dfs = df.shift(-1)
m1 = df.ID == dfs.ID
m2 = df.Rank + 1 == dfs.Rank
df.loc[:, 'C_End'] = np.where(m1 & m2, dfs.C_Type, None)

   ID    C_ID C_Type  Rank C_End
0  123     8    New     1  Renew
1  123    10  Renew     2  Renew
2  123    35  Renew     3   None
3  456    36    New     1   Term
4  456    40   Term     2   None
5  789     7    New     1   None