#python #pandas #dataframe #pyspark #data-transform
Вопрос:
У меня есть таблица, которую я не создавал, в моей базе данных sql server, которая выглядит следующим образом.
идентификатор менеджера | информация о сотруднике |
---|---|
123567890123 | [{’emp_name’:’ash’,’emp_id’:’123′},{{’emp_name’:’брэд’,’emp_id’:’234′}] |
235678901234 | [{’emp_name’:’sarah’,’emp_id’:’345′},{{’emp_name’:’ryan’,’emp_id’:’456′}{{’emp_name’:’chris’,’emp_id’:’567′}] |
Я запросил эту таблицу и вошел в фрейм данных pandas. Я хочу получить каждое имя emp_name и идентификатор emp_id для каждого менеджера Ниже-это мой желаемый результат.
идентификатор менеджера | emp_name | emp_id |
---|---|---|
123567890123 | пепел | 123 |
123567890123 | штифтик | 234 |
235678901234 | Сара | 345 |
235678901234 | Райан | 456 |
235678901234 | Крис | 567 |
Комментарии:
1. Это не JSON. В JSON используются двойные кавычки, а не одинарные кавычки.
2. И
{{
должно быть просто{
3. Предполагая
{{
, что это просто ошибка копирования, вы можете использоватьast.literal_eval()
ее для анализаemployee_info
.4. Затем вы можете выполнить итерацию по списку, чтобы создать новые строки в результирующем df.
5. @Бармар. 3 раза
'{{'
. Вероятно, это не ошибка копирования, и нет запятой для разделения разных элементов (строка 2).
Ответ №1:
Вы можете использовать .explode()
для расширения списка json в отдельные json по одному на строку. Затем используйте pd.Series
для преобразования json в столбцы.
df2 = df.explode('employee info').reset_index(drop=True)
df_out = df2.join(df2['employee info'].apply(pd.Series)).drop('employee info', axis=1)
Для повышения производительности вы можете использовать pd.DataFrame()
вместо pd.Series
преобразования json в столбцы, как показано ниже:
pd.DataFrame(df2['employee info'].tolist())
emp_name emp_id
0 ash 123
1 brad 234
2 sarah 345
3 ryan 456
4 chris 567
Весь набор кодов выглядит следующим образом:
df2 = df.explode('employee info').reset_index(drop=True)
df_out = df2.join(pd.DataFrame(df2['employee info'].tolist())).drop('employee info', axis=1)
Ввод Данных
data = {'manager id': [123567890123, 235678901234],
'employee info': [[{'emp_name':'ash','emp_id':'123'},{'emp_name':'brad','emp_id':'234'}],
[{'emp_name':'sarah','emp_id':'345'},{'emp_name':'ryan','emp_id':'456'}, {'emp_name':'chris','emp_id':'567'}]]}
df = pd.DataFrame(data)
Выход:
print(df_out)
manager id emp_name emp_id
0 123567890123 ash 123
1 123567890123 brad 234
2 235678901234 sarah 345
3 235678901234 ryan 456
4 235678901234 chris 567
Комментарии:
1. Вы предполагаете
employee info
, что столбец — это не строка, а реальный список python? Почему нет.2. @Corralien Просто дикое предположение.
3. Я согласен с этим. Возможно, запрос выполняется с Python и связан с Пандами. Идея хорошая 1
Ответ №2:
Вы можете использовать ast.literal_eval
для получения ожидаемого результата:
import ast
out = df['employee info'].apply(ast.literal_eval).explode().apply(pd.Series)
emp_name emp_id
0 ash 123
0 brad 234
1 sarah 345
1 ryan 456
1 chris 567
out = pd.concat([df['manager id'], out], axis='columns')
Выход:
>>> df
manager id emp_name emp_id
0 123567890123 ash 123
0 123567890123 brad 234
1 235678901234 sarah 345
1 235678901234 ryan 456
1 235678901234 chris 567
Я немного изменил ваш фрейм данных:
data = {'manager id': [123567890123, 235678901234],
'employee info': ["[{'emp_name':'ash','emp_id':'123'},{'emp_name':'brad','emp_id':'234'}]",
"[{'emp_name':'sarah','emp_id':'345'},{'emp_name':'ryan','emp_id':'456'},{'emp_name':'chris','emp_id':'567'}]"]}
df = pd.DataFrame(data)
Комментарии:
1. Предполагая, что синтаксические проблемы в
employee_info
столбце исправлены.2. @Бармар. Да, я исправил вручную. Я удалил
{{
и добавил отсутствующие,
.