Как сгенерировать запрос на основе шаблона? - PullRequest
1 голос
/ 17 октября 2019

У меня есть кадр данных, как показано ниже

df = pd.DataFrame({
'R_Id':[11,21,3,14,51,22],
'R_name' : ['READ_11','READ_21','READ_3','READ_14','READ_51','READ_22']
})

enter image description here

Обратите внимание, что df будет содержать только уникальные идентификаторы

Это запрос, который я писал вручную

select person_id,
   count(*) filter (where reading = 11) as cnt_read_11,
   min(value) filter (where reading = 11) as min_read_11,
   max(value) filter (where reading = 11) as max_read_11,
   avg(value) filter (where reading = 11) as avg_read_11,
   stddev(value) filter (where reading = 11) as stdev_read_11,
   count(*) filter (where reading = 21) as cnt_read_21,
   min(value) filter (where reading = 21) as min_read_21,
   max(value) filter (where reading = 21) as max_read_21,
   avg(value) filter (where reading = 21) as avg_read_21,
   stddev(value) filter (where reading = 21) as stdev_read_21,
   from table
   group by person_id;

Как видите, шаблон следует трем правилам

a) В каждом чтении будет 5 операторов (count,min,max,avg,stddev)

b) Извлеките R_Id из df и поместите его в where условие

c) Извлеките R_name из df и поставьте его в конце имени каждого столбца. Пример: cnt_read_11, min_read_11 и т. Д.

Можете ли вы помочь мне автоматизировать это и сгенерировать запрос для всех показаний, присутствующих в df ?

1 Ответ

1 голос
/ 17 октября 2019

Вы можете указать шаблоны с """ и установить значения в f-строках с itertuples:

head = """
select person_id,"""

tail="""from table
    group by person_id;

"""

out = []
for t in df.itertuples():
    temp = f"""
       count(*) filter (where reading = {t.R_Id}) as cnt_{t.R_name},
       min(value) filter (where reading = {t.R_Id}) as min_{t.R_name},
       max(value) filter (where reading = {t.R_Id}) as max_{t.R_name},
       avg(value) filter (where reading = {t.R_Id}) as avg_{t.R_name},
       stddev(value) filter (where reading = {t.R_Id}) as stdev_{t.R_name},
    """
    out.append(temp)

fin = head + ''.join(out) + tail
print (fin)

select person_id,
       count(*) filter (where reading = 11) as cnt_READ_11,
       min(value) filter (where reading = 11) as min_READ_11,
       max(value) filter (where reading = 11) as max_READ_11,
       avg(value) filter (where reading = 11) as avg_READ_11,
       stddev(value) filter (where reading = 11) as stdev_READ_11,

       count(*) filter (where reading = 21) as cnt_READ_21,
       min(value) filter (where reading = 21) as min_READ_21,
       max(value) filter (where reading = 21) as max_READ_21,
       avg(value) filter (where reading = 21) as avg_READ_21,
       stddev(value) filter (where reading = 21) as stdev_READ_21,

       count(*) filter (where reading = 3) as cnt_READ_3,
       min(value) filter (where reading = 3) as min_READ_3,
       max(value) filter (where reading = 3) as max_READ_3,
       avg(value) filter (where reading = 3) as avg_READ_3,
       stddev(value) filter (where reading = 3) as stdev_READ_3,

       count(*) filter (where reading = 14) as cnt_READ_14,
       min(value) filter (where reading = 14) as min_READ_14,
       max(value) filter (where reading = 14) as max_READ_14,
       avg(value) filter (where reading = 14) as avg_READ_14,
       stddev(value) filter (where reading = 14) as stdev_READ_14,

       count(*) filter (where reading = 51) as cnt_READ_51,
       min(value) filter (where reading = 51) as min_READ_51,
       max(value) filter (where reading = 51) as max_READ_51,
       avg(value) filter (where reading = 51) as avg_READ_51,
       stddev(value) filter (where reading = 51) as stdev_READ_51,

       count(*) filter (where reading = 22) as cnt_READ_22,
       min(value) filter (where reading = 22) as min_READ_22,
       max(value) filter (where reading = 22) as max_READ_22,
       avg(value) filter (where reading = 22) as avg_READ_22,
       stddev(value) filter (where reading = 22) as stdev_READ_22,
    from table
    group by person_id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...