Столбец с массивами в столбцы (Bigquery)

#sql #dataframe #google-bigquery

# #sql #фрейм данных #google-bigquery

Вопрос:

Я новичок в bigquery и dataframes, и я хочу что-то сделать с этой следующей таблицей: Таблица

Как вы видите, у меня есть массив itemid и соответствующее ему значение в столбце value для каждого пользователя (очевидно, они имеют одинаковую длину). Что я хочу сделать, так это создать столбец для каждого itemid, а затем указать значение в этом столбце для конкретного пользователя. Например, будут столбцы с именами 51493, 51516 и так далее, а для первого пользователя значение в столбце 51943 будет равно 2 и так далее, и null для любого другого пользователя, у которого нет значения для 51943.

Я предполагаю, что синтаксический анализ с помощью for внутри цикла for крайне неэффективен, и, поскольку я новичок в dataframes, я хотел бы получить некоторую помощь, чтобы сделать это эффективно. Спасибо!

Для запроса это запрос bigquery, который дал мне эти данные:

 %%bigquery lab_m_df
SELECT
  # MIMIC3 sets all ages over 89 to 300 to avoid the possibility of
  # identification.
  IF(DATETIME_DIFF(ADMITTIME, DOB, DAY)/365.25 < 200,
     DATETIME_DIFF(ADMITTIME, DOB, DAY)/365.25,
     # The life expectancy of a 90 year old is approximately 5 years according
     # to actuarial tables. So we'll use 95 as the mean age of 90 's
     95) AS age,
  gender,
  admission_type,
  itemids,
  value,
  admission_location,
  insurance,
  marital_status,
  ethnicity,
  died
FROM
  (SELECT
    ARRAY_AGG(ITEMID) as itemids,
    ARRAY_AGG(IFNULL(VALUE, 'null')) as value,
    MAX(HOSPITAL_EXPIRE_FLAG) as died,
    ANY_VALUE(ADMITTIME) as ADMITTIME,
    ANY_VALUE(ADMISSION_TYPE) as admission_type,
    ANY_VALUE(ADMISSION_LOCATION) as admission_location,
    ANY_VALUE(INSURANCE) as insurance,
    ANY_VALUE(MARITAL_STATUS) as marital_status,
    ANY_VALUE(ETHNICITY) as ethnicity, 
    HADM_ID,
    SUBJECT_ID
  FROM
    `{admissions_table}` AS adm
    JOIN `{labevents_table}` AS diag
  USING (HADM_ID, SUBJECT_ID)
  WHERE DATETIME_DIFF(CHARTTIME, ADMITTIME, HOUR) <= 4
  GROUP BY HADM_ID, SUBJECT_ID
  )
  JOIN `{patients_table}` AS patients
  USING (SUBJECT_ID) 
 

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

1. Пожалуйста, покажите данные, с которых вы начинаете.

2. @GordonLinoff Привет, я загрузил запрос bigquery, который выдает мне эту таблицу, поскольку данные большие. Но я предполагаю, что этого запроса достаточно, чтобы понять таблицу, из которой я беру данные, это полезно?

Ответ №1:

То, что вы хотите сделать, довольно сложно. Лучшим подходом является отдельная строка для каждой пары:

 select t.personid, itemid, val
from t cross join
     unnest(itemids) itemid with offset ni join
     unnest(value) val with offset nv
     on ni = nv;
 

Если вы знаете, какие элементы вас интересуют, сгенерировать столбцы просто:

 select t.personid,
       max(case when itemid = 1 then val end) as item1,
       max(case when itemid = 2 then val end) as item2,
       max(case when itemid = 3 then val end) as item3,
       . . .
from t cross join
     unnest(itemids) itemid with offset ni join
     unnest(value) val with offset nv
     on ni = nv
group by t.personid
 

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

1. Я знаю, какие элементы меня волнуют. Меня волнует конкретно 40 itemid. Есть ли способ создать 40 столбцов более эстетичным способом вместо того, чтобы делать 40 строк «max (случай, когда itemid = 1, затем val end) как item1»?

2. @The_C . , , я бы предложил просто использовать max() выражения.