#python #pandas #dataframe
Вопрос:
У меня есть фрейм данных присутствия/отсутствия, который выглядит следующим образом (он намного больше, но уменьшил его для этого вопроса).:
annotations factor1 factor2 factor3 Class heroine 1 0 1 OPIOID_TYPE he smokes 0 1 0 OTHER_DRUG_USE heroin 1 0 1 OPIOID_TYPE
Что я хотел бы сделать, так это создать новый фрейм данных для каждого уникального значения в «Классе» и вставить каждое значение в класс в качестве имени последнего столбца для каждого фрейма данных и записать наличие/отсутствие.
Другими словами:
annotations factor1 factor2 factor3 OPIOID_TYPE heroine 1 0 1 1 he smokes 0 1 0 0 heroin 1 0 1 1
и:
annotations factor1 factor2 factor3 OTHER_DRUG_USE heroine 1 0 1 0 he smokes 0 1 0 1 heroin 1 0 1 0
На самом деле мой фрейм данных намного больше: 2289 строк и 1273 столбца и ровно 23 уникальных значения в «Классе» для 23 новых фреймов данных.
Я предполагаю, что здесь будет работать структура цикла, но у меня ограниченный опыт работы с циклами python.
Ответ №1:
Вы можете перебирать свои Class
значения:
dfs = {} for klass in df['Class'].unique(): dfs[klass] = df.assign(**{klass: df['Class'].eq(klass).astype(int)}) .drop(columns='Class')
Теперь у вас есть диктант, индексированный по Class
значениям:
gt;gt;gt; dfs.keys() dict_keys(['OPIOID_TYPE', 'OTHER_DRUG_USE']) gt;gt;gt; dfs['OPIOID_TYPE'] annotations factor1 factor2 factor3 OPIOID_TYPE 0 heroine 1 0 1 1 1 he smokes 0 1 0 0 2 heroin 1 0 1 1 gt;gt;gt; dfs['OTHER_DRUG_USE'] annotations factor1 factor2 factor3 OTHER_DRUG_USE 0 heroine 1 0 1 0 1 he smokes 0 1 0 1 2 heroin 1 0 1 0
Настоятельно не рекомендуется следующее
Теперь, если вам действительно нужны реальные переменные python, вы можете использовать locals()
их для динамического создания:
for idx, klass in enumerate(df['Class'].unique(), 1): print(f"df{idx} is for '{klass}' class") locals()[f"df{idx}"] = df.assign(**{klass: df['Class'].eq(klass).astype(int)}) .drop(columns='Class') # Output: df1 is for 'OPIOID_TYPE' class df2 is for 'OTHER_DRUG_USE' class
Выход:
gt;gt;gt; df1 annotations factor1 factor2 factor3 OPIOID_TYPE 0 heroine 1 0 1 1 1 he smokes 0 1 0 0 2 heroin 1 0 1 1 gt;gt;gt; df2 annotations factor1 factor2 factor3 OTHER_DRUG_USE 0 heroine 1 0 1 0 1 he smokes 0 1 0 1 2 heroin 1 0 1 0
Комментарии:
1. Спасибо! Я не совсем уверен, что происходит во второй части, но есть ли способ извлечь каждый «кадр данных» в дикте для ряда объектов? т. е. df1 — df23?
2. Вторая часть-это то, что вы хотите, динамически создавать переменные. Я обновил свой ответ на основе вашего комментария. Теперь вы можете использовать df1, df2, …, df23 в качестве независимых кадров данных.
Ответ №2:
Мы можем сделать get_dummies
и сохранить dfs в dict
s = df.pop('Class').str.get_dummies() d = {x : df.join(s[[x]]) for x in s}
Пример вывода ниже
d['OPIOID_TYPE'] Out[43]: annotations factor1 factor2 factor3 OPIOID_TYPE 0 heroine 1 0 1 1 1 hesmokes 0 1 0 0 2 heroin 1 0 1 1 d['OTHER_DRUG_USE'] Out[44]: annotations factor1 factor2 factor3 OTHER_DRUG_USE 0 heroine 1 0 1 0 1 hesmokes 0 1 0 1 2 heroin 1 0 1 0
Комментарии:
1. Большое вам спасибо! Есть ли способ извлечь каждый из них в виде отдельных кадров данных из диктанта?