С помощью Python , как я могу запрашивать элементы в столбце в формате json и преобразовывать их в строки?

#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. @Бармар. Да, я исправил вручную. Я удалил {{ и добавил отсутствующие , .