将SAS代码转换为与groupby.first()等效的Pandas并保留函数

时间:2016-12-06 17:53:49

标签: python pandas numpy sas

我有SAS代码,我需要转换成python pandas。

   data df1;
   set df;
       by id;
       retain flag_final;
       if first.id then do;
          if flag eq 0 then flag_final=flag;
          else flag_final=.;
       end;
       else do;
          flag_final=flag_final;
   run;

我在熊猫中尝试过类似的东西,但它不起作用我的意思是我无法将if else条件放入我的merge子句中。如果某人更好地了解如何完成它将会非常有帮助

  df_temp=df[['id','flag']]
  df1= df.merge(df_temp.groupby('id').first().reset_index(), on='id').rename(
columns={'flag_x':'flag', 'flag_y':'flag_final'})

注意:即使我无法理解obove SAS代码。所以不能放任何示例输入和输出数据集。如果有人知道SAS可以帮助我理解它,那么我可以把它转换成熊猫。或者你有一些方法请建议。

编辑:添加输入和输出数据集:

输入数据框:

  import pandas as pd
  import numpy as np

 df = pd.DataFrame({'id': [1,1,2,1,2,2,3,3,4,3,3,4,4,4], 'flag': [np.nan,0,1,'p','q',0,"",2,0,'r',np.nan,0,1,np.nan]})
 df=df.sort_values('id')

  id      flag

  1         NaN
  1         0
  1         p
  2         1
  2         q
  2         0
  3         ""
  3         2
  3         r
  3         NaN
  4         0
  4         0
  4         1
  4        NaN

输出数据集:

  id      flag     flag_final

  1         NaN     .
  1         0       .
  1         p       .
  2         1       .
  2         q       .
  2         0       .   
  3         ""      .
  3         2       .
  3         r       .
  3         NaN     .
  4         0       0
  4         0       0
  4         1       0
  4        NaN      0

我试过这样但不起作用:

df=df.sort_values('id')
df.loc[:,'flag_final']=df
df['flag_final']=np.where(df['id'].first,np.where(df['flag'].iloc[0]==0,df['flag'],'.'),np.nan)    

2 个答案:

答案 0 :(得分:1)

逐行分解:

 data df1;
   set df;

创建一个名为df1的新数据集,并逐行将df中的值读入其中。

by id;

逐行阅读df时,请按变量id排序阅读。

retain flag_final;

在阅读新行时,请将flag_final初始化为最后一个值。

if first.id then do;

如果它是有序ID标识块中的第一个ID,请执行一些功能。

if flag eq 0 then flag_final = flag;
    else flag_final = .;
end;

如果变量flag为0,则使变量flag_final取值为flag。否则,将变量flag_final设为缺失值。

else do;
    flag_final = flag_final;
end;

如果它不是组中ID的第一个值,请将flag_final的值设置为自身。

new_col = id;

创建一个名为new_col的新变量,其值为id

run;

数据步骤的结束。

答案 1 :(得分:0)

你走了:

dfy = pd.DataFrame({'id': [1,1,2,1,2,2,3,3,4,3,3,4,4,4], 'flag': [np.nan,0,1,'p','q',0,"",2,0,'r',np.nan,0,1,np.nan]})
dfy["flag_final"] = np.nan
def func1(group):
    if group.flag.values[0] == 0:
        group.flag_final.values[0] = "0"
    else:
        group.flag_final.values[0] = "1"
    return group

dfy.sort_values('id', inplace=True)
dfy = dfy.groupby(['id']).apply(func1).fillna(method='ffill')
dfy["flag_final"] = dfy["flag_final"].map({0:0, 1:"." })

我试图弄清楚如何添加一个带有NaN值的空对象列,这样我就可以通过更改" 1"来消除最后一行。在函数func1到"。"