Как переписать этот SQL-запрос в Python с пандами? - PullRequest
0 голосов
/ 10 декабря 2018

Как я могу перевести следующий запрос, используя панды в Python?

SELECT Id,
           MIN(CASE WHEN Type = 0001 THEN Date END) AS TransactionDate,
           MIN(CASE WHEN Type = 0002 THEN Date END) AS SignupDate,
           MIN(CASE WHEN Type = 0003 THEN Date END) AS SeenDate
FROM Transactions
WHERE State = 0
GROUP BY Id

Я могу сделать это для первого столбца, как это:

transactionDate = transactions[transactions["Type"] == "0001"].groupby("Id")["Date"].min()

Но это кажетсяочень неэффективно, так как мне придется повторять группу несколько раз.Меня больше всего смущает то, как я могу применить 3 различных фильтра к наборам строк после групповой работы.Есть ли более эффективный способ сделать это?

1 Ответ

0 голосов
/ 11 декабря 2018

Рассмотрим два подхода: назначение столбцов перед агрегированием или агрегированием условно встроенных, а затем отбрасывание дубликатов:

Подход 1

transactionDate = (transactions.assign(TransactionDate = transactions['Date'].where(transactions['Type']=='0001'),
                                       SignupDate = transactions['Date'].where(transactions['Type']=='0002'),
                                       SeenDate = transactions['Date'].where(transactions['Type']=='0003')
                                       )
                               .groupby("Id")
                               .agg({'TransactionDate':'min', 'SignupDate':'min', 'SeenDate':'min'})    
                               .reindex(['TransactionDate', 'SignupDate', 'SeenDate'], axis='columns')
                   )

Подход 2

def agg_cols(row):
   row['TransactionDate'] = row[row["Type"] == "0001"]["Date"].min()
   row['SignupDate'] = row[row["Type"] == "0002"]["Date"].min()
   row['SeenDate'] = row[row["Type"] == "0003"]["Date"].min()

   return row

transactionDate = (transactions.groupby("Id")
                                .apply(agg_cols)
                                .reindex(['Id', 'TransactionDate', 'SignupDate', 'SeenDate'], axis='columns')
                                .drop_duplicates()
                                .sort_values('Id')
                                .reset_index(drop=True)
                   )

Данные

Для демонстрации со случайными данными (для воспроизводимости):

import numpy as np
import pandas as pd

np.random.seed(12102018)
transactions = pd.DataFrame({'Type': np.random.choice(['0001', '0002', '0003'], 344),
                             'Id': np.random.choice(['r', 'pandas', 'julia', 'sas', 'stata', 'spss'], 344),
                             'Date': pd.date_range('2018-01-01', '2018-12-10')
                            })

Вывод

Подход 1

#        TransactionDate SignupDate   SeenDate
# Id                                          
# julia       2018-01-13 2018-01-19 2018-05-02
# pandas      2018-01-08 2018-01-09 2018-01-29
# r           2018-01-03 2018-01-15 2018-01-02
# sas         2018-01-12 2018-01-22 2018-01-07
# spss        2018-01-05 2018-02-19 2018-01-01
# stata       2018-01-16 2018-01-30 2018-01-20

Подход 2

#        Id TransactionDate SignupDate   SeenDate
# 0   julia      2018-01-13 2018-01-19 2018-05-02
# 1  pandas      2018-01-08 2018-01-09 2018-01-29
# 2       r      2018-01-03 2018-01-15 2018-01-02
# 3     sas      2018-01-12 2018-01-22 2018-01-07
# 4    spss      2018-01-05 2018-02-19 2018-01-01
# 5   stata      2018-01-16 2018-01-30 2018-01-20
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...