Как написать оператор if из SAS в python

#python #sas

#python #sas

Вопрос:

Я пользователь SAS, который пытается преобразовать код SAS в версию python.

Я создал код SAS, как показано ниже, и у меня возникли некоторые проблемы с применением к языку python. Предполагается, что у меня есть таблица данных, которая содержит поля с возрастом от 1 до 60 лет, и я хочу создать два новых поля с именами ‘life_def’ и ‘obs_time’. Эти два поля содержали значение 0 и будут изменены на основе условия из других полей, возраст которых составляет от 1 до 60 лет.

 data want;
set have;
array aging_array(*) aging1--aging60;

life_def=0;
obs_time=0;

do i to 60;
     if life_def=0 and aging_array[i] ne . then do;
          if aging_array[i]>=4 then do;
               obs_time=i;
               life_def=1;
               end;
     if aging_array[i]<4 then do;
               obs_time=i;
               end;
           end;
end;

drop i;
run;
  

Я попытался воссоздать приведенный выше код SAS в версию python, но, тем не менее, это не сработало. Ниже приведен мой код, над которым я сейчас работаю.

 df['life_def']=0
df['obs_time']=0

for i in range(1,lag 1):
    if df['life_def'].all()==0 and pd.notnull(df[df.columns[i 4]].all()):
        condition=df[df.columns[i 4]]>=4
        df['life_def']=np.where(condition, 1, df['life_def'])
        df['obs_time']=np.where(condition, i, df['obs_time'])
  

Предполагаемый df[df.columns[i 4]] — это мои устаревшие столбцы в SAS. Используя приведенный выше код, цикл продолжается при увеличении i. Однако логика из предоставленного SAS заключается в том, чтобы остановить i при первом старении> = 4.

Например, если возраст 7>= 4 (в первый раз), life_def будет равен 1, а obs_time будет равен 7, и назначьте следующий цикл, который равен 8.

Спасибо!

Комментарии:

1. Я думаю, что в данном конкретном случае попытка выполнить «прямое» преобразование непрактична, я подозреваю, что есть некоторые функции python, которые могут значительно упростить эту логику. Какова общая логика, найти первую запись поверх 4?

2. @Reeza Привет, логика заключается в том, чтобы подсчитать, сколько раз это касалось старения > = 4 в каждом цикле

3. 2-й блок в python не работает? В чем ошибка msg? Я вижу опечатку в строке 7: скобок ' слишком много. —> if df['aging' str(i)]>=4:

4. @stallingOne Я отредактировал код, но результаты не соответствуют SAS. Есть предложения по этому поводу?

5. Это список или фрейм данных?

Ответ №1:

Ваша цель — получить первый aging**x** столбец x (для каждой строки), который равен ge 4. Приведенный ниже фрагмент будет делать то же самое.

Примечание — я использую python 2.7

 mydf['obs_time'] = 0

agingcols_len = len([k for k in mydf.columns.tolist() if 'aging' in k])
rowcnt = mydf['aging1'].fillna(0).count()

for k in xrange(rowcnt):
    isFirst = True
    for i in xrange(1, agingcols_len):
        if isFirst and mydf['aging'   str(i)][k] >= 4:
            mydf['obs_time'][k] = i
            isFirst = False
        elif isFirst and mydf['aging'   str(i)][k] < 4:
            pass
  

Я загрузил данные, которые я использовал для тестирования выше. То же самое можно найти здесь.

Фрагмент перебирает все aging**x** столбцы (например, — aging1 , aging2 ) и продолжает увеличивать obs_time , пока он не станет больше или равен 4. Все это повторяется по DataFrame строкам с k помощью.

К вашему сведению — Однако это очень медленно, когда вам нужно перебирать миллионы строк.

Комментарии:

1. К вашему СВЕДЕНИЮ — Приведенный выше фрагмент python предназначен для имитации шага передачи данных SAS как есть. Могут быть другие оптимизированные способы достижения требуемого вывода и логики.

2. Спасибо, что поделились, я попробую это.