Расширить временные ряды для каждой группы на панели - PullRequest
1 голос
/ 09 октября 2019

У меня есть следующая база данных:

firm    sic     identifier  name                    year    X           Y           Z
1078    2834.0  002824100   ABBOTT LABORATORIES     2013    4.347826    5.217391    15.739130   
1078    2834.0  002824100   ABBOTT LABORATORIES     2014    4.368421    6.263158    16.684211   
112178  2836.0  00339B107   ABGENIX INC             2005    5.222222    3.111111    9.777778    
112178  2836.0  00339B107   ABGENIX INC             2006    5.222222    4.111111    10.777778     
178855  2836.0  00383Y102   ABRAXIS BIOSCIENCE INC  2007    4.000000    0.000000    13.544322   

Я намерен продлить переменную года на 5 лет назад для каждой группы. Столбцы фирмы, sic, идентификатора и имени необходимо будет скопировать в новые строки. Однако столбцы X, Y и Z будут NAN.

Предполагаемый результат:

firm    sic     identifier  name                    year    X           Y           Z
1078    2834.0  002824100   ABBOTT LABORATORIES     2008    NAN         NAN         NAN
1078    2834.0  002824100   ABBOTT LABORATORIES     2009    NAN         NAN         NAN
1078    2834.0  002824100   ABBOTT LABORATORIES     2010    NAN         NAN         NAN  
1078    2834.0  002824100   ABBOTT LABORATORIES     2011    NAN         NAN         NAN
1078    2834.0  002824100   ABBOTT LABORATORIES     2012    NAN         NAN         NAN
1078    2834.0  002824100   ABBOTT LABORATORIES     2013    4.347826    5.217391    15.739130   
1078    2834.0  002824100   ABBOTT LABORATORIES     2014    4.368421    6.263158    16.684211   
112178  2836.0  00339B107   ABGENIX INC             2000    NAN         NAN         NAN 
112178  2836.0  00339B107   ABGENIX INC             2001    NAN         NAN         NAN
112178  2836.0  00339B107   ABGENIX INC             2002    NAN         NAN         NAN 
112178  2836.0  00339B107   ABGENIX INC             2003    NAN         NAN         NAN 
112178  2836.0  00339B107   ABGENIX INC             2004    NAN         NAN         NAN 
112178  2836.0  00339B107   ABGENIX INC             2005    4.454545    3.181818    11.000000
112178  2836.0  00339B107   ABGENIX INC             2006    4.222222    4.000000    13.555556
178855  2836.0  00383Y102   ABRAXIS BIOSCIENCE INC  2007    NAN         NAN         NAN 
178855  2836.0  00383Y102   ABRAXIS BIOSCIENCE INC  2007    NAN         NAN         NAN         
178855  2836.0  00383Y102   ABRAXIS BIOSCIENCE INC  2007    NAN         NAN         NAN 
178855  2836.0  00383Y102   ABRAXIS BIOSCIENCE INC  2007    NAN         NAN         NAN         
178855  2836.0  00383Y102   ABRAXIS BIOSCIENCE INC  2007    NAN         NAN         NAN     
178855  2836.0  00383Y102   ABRAXIS BIOSCIENCE INC  2007    4.000000    0.000000    13.544322       

Если у вас есть идеи, как реализовать это в python, поделитесь ими со мной.

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 09 октября 2019

Вы можете использовать index.repeat и merge

f = df.groupby('firm').first()
d = f.loc[f.index.repeat(5)]

d.assign(year=d.year+np.tile(np.arange(-5, 0), len(f)),
           X=np.nan,
           Y=np.nan,
           Z=np.nan)\
 .merge(df.set_index('firm'), how='outer')\
 .sort_values(['identifier', 'year'])

      sic identifier                    name  year         X         Y          Z
0   2834.0  002824100     ABBOTT LABORATORIES  2008       NaN       NaN        NaN
1   2834.0  002824100     ABBOTT LABORATORIES  2009       NaN       NaN        NaN
2   2834.0  002824100     ABBOTT LABORATORIES  2010       NaN       NaN        NaN
3   2834.0  002824100     ABBOTT LABORATORIES  2011       NaN       NaN        NaN
4   2834.0  002824100     ABBOTT LABORATORIES  2012       NaN       NaN        NaN
15  2834.0  002824100     ABBOTT LABORATORIES  2013  4.347826  5.217391  15.739130
16  2834.0  002824100     ABBOTT LABORATORIES  2014  4.368421  6.263158  16.684211
5   2836.0  00339B107             ABGENIX INC  2000       NaN       NaN        NaN
6   2836.0  00339B107             ABGENIX INC  2001       NaN       NaN        NaN
7   2836.0  00339B107             ABGENIX INC  2002       NaN       NaN        NaN
8   2836.0  00339B107             ABGENIX INC  2003       NaN       NaN        NaN
9   2836.0  00339B107             ABGENIX INC  2004       NaN       NaN        NaN
17  2836.0  00339B107             ABGENIX INC  2005  5.222222  3.111111   9.777778
18  2836.0  00339B107             ABGENIX INC  2006  5.222222  4.111111  10.777778
10  2836.0  00383Y102  ABRAXIS BIOSCIENCE INC  2002       NaN       NaN        NaN
11  2836.0  00383Y102  ABRAXIS BIOSCIENCE INC  2003       NaN       NaN        NaN
12  2836.0  00383Y102  ABRAXIS BIOSCIENCE INC  2004       NaN       NaN        NaN
13  2836.0  00383Y102  ABRAXIS BIOSCIENCE INC  2005       NaN       NaN        NaN
14  2836.0  00383Y102  ABRAXIS BIOSCIENCE INC  2006       NaN       NaN        NaN
19  2836.0  00383Y102  ABRAXIS BIOSCIENCE INC  2007  4.000000  0.000000  13.544322
2 голосов
/ 09 октября 2019

IIUC вы можете играть с groupby explode и merge, как показано в следующем коде

import pandas as pd
# Sanity check
df["year"] = df["year"].astype(int)

# groupby + explode
cols = ["firm","sic", "identifier", "name", "year"]
grp = df.groupby(cols[:-1])\
        .agg({"year":{"min","max"}})\
        .apply(lambda x: np.arange(x["year"]["min"]-5,
                                   x["year"]["max"]+1),
               axis=1)\
        .reset_index(name="year")\
        .explode("year")\
        .reset_index(drop=True)

grp["year"] = grp["year"].astype(int)

# merge
df = pd.merge(grp,df, on=cols, how="left")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...