我正在尝试将一列“ 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)
答案 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