#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()
выражения.