#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. Спасибо, что поделились, я попробую это.