通过扩展日期将观察结果添加到pandas数据框中

时间:2015-12-17 20:03:34

标签: python pandas

我有一个像这样的熊猫系列:

sid     qtr
84024   1998-09-30
89565   2007-06-30
73083   1991-06-30
77447   2003-12-31
71079   1992-12-31

对于每一行,我想再创建3行,对应每个sid的下三个季度。

我已经提出了这种方法,但我想知道是否有更多的pandamic方法来做到这一点:

df = df.set_index('sid')
for k in xrange(4):
    df['q' + str(k+1)] = pd.DatetimeIndex(df['qtr']) + pd.offsets.QuarterEnd(k+1)
df = df.unstack()
df.index = df.index.get_level_values(1)
df = df.sort_values()

2 个答案:

答案 0 :(得分:1)

我将季度(字符串)转换为季度Period对象。然后我使用列表推导来生成接下来的三个季度中的每一个。所有这些都包含在sid上的字典理解中,用于生成名为df2的新数据框。

df2 = pd.DataFrame({row.sid: [pd.Period(row.qtr, 'Q') + n for n in range(4)] 
                             for _, row in df.iterrows()}).T.reset_index()

>>> df2
   index       0       1       2       3
0  71079  1992Q4  1993Q1  1993Q2  1993Q3
1  73083  1991Q2  1991Q3  1991Q4  1992Q1
2  77447  2003Q4  2004Q1  2004Q2  2004Q3
3  84024  1998Q3  1998Q4  1999Q1  1999Q2
4  89565  2007Q2  2007Q3  2007Q4  2008Q1

然后我使用melt来获取同一列中的所有季度。

df2 = pd.melt(df2, id_vars='index')
df2.rename(columns={'index': 'sid', 'value': 'qtr', 'variable': 'offset'}, inplace=True)

>>> df2
      sid offset     qtr
0   71079      0  1992Q4
1   73083      0  1991Q2
2   77447      0  2003Q4
3   84024      0  1998Q3
4   89565      0  2007Q2
5   71079      1  1993Q1
6   73083      1  1991Q3
7   77447      1  2004Q1
8   84024      1  1998Q4
9   89565      1  2007Q3
10  71079      2  1993Q2
11  73083      2  1991Q4
12  77447      2  2004Q2
13  84024      2  1999Q1
14  89565      2  2007Q4
15  71079      3  1993Q3
16  73083      3  1992Q1
17  77447      3  2004Q3
18  84024      3  1999Q2
19  89565      3  2008Q1

答案 1 :(得分:1)

这是一种完全不同的方法。

创建Period对象非常昂贵,所以让我们确定唯一的四分之一,然后应用句点映射。

quarters = df.qtr.unique().tolist()
mapping = {qtr: [pd.to_datetime(qtr) + pd.offsets.QuarterEnd(q) 
                 for q in range(4)] 
           for qtr in quarters}

>>> mapping
{'1991-06-30': [Timestamp('1991-06-30 00:00:00'),
  Timestamp('1991-09-30 00:00:00'),
  Timestamp('1991-12-31 00:00:00'),
  Timestamp('1992-03-31 00:00:00')],
 '1992-12-31': [Timestamp('1992-12-31 00:00:00'),
  Timestamp('1993-03-31 00:00:00'),
  Timestamp('1993-06-30 00:00:00'),
  Timestamp('1993-09-30 00:00:00')],
 '1998-09-30': [Timestamp('1998-09-30 00:00:00'),
  Timestamp('1998-12-31 00:00:00'),
  Timestamp('1999-03-31 00:00:00'),
  Timestamp('1999-06-30 00:00:00')],
 '2003-12-31': [Timestamp('2003-12-31 00:00:00'),
  Timestamp('2004-03-31 00:00:00'),
  Timestamp('2004-06-30 00:00:00'),
  Timestamp('2004-09-30 00:00:00')],
 '2007-06-30': [Timestamp('2007-06-30 00:00:00'),
  Timestamp('2007-09-30 00:00:00'),
  Timestamp('2007-12-31 00:00:00'),
  Timestamp('2008-03-31 00:00:00')]}

现在我们可以在初始数据框中映射qtr列,并使用列表推导来提取四个季度中的每一个。然后使用sid压缩这些值。

df2 = pd.DataFrame(zip(df.sid.tolist() * 4, 
                       [q[i] for i in range(4) 
                        for q in df.qtr.map(mapping).values.tolist()]), 
                   columns=['sid', 'qtr'])
df2 = df2.sort_values('sid').reset_index(drop=True)

>>> df2
      sid        qtr
0   71079 1993-03-31
1   71079 1993-06-30
2   71079 1992-12-31
3   71079 1993-09-30
4   73083 1991-06-30
5   73083 1991-09-30
6   73083 1991-12-31
7   73083 1992-03-31
8   77447 2004-03-31
9   77447 2004-09-30
10  77447 2004-06-30
11  77447 2003-12-31
12  84024 1998-12-31
13  84024 1999-03-31
14  84024 1999-06-30
15  84024 1998-09-30
16  89565 2007-09-30
17  89565 2007-12-31
18  89565 2007-06-30
19  89565 2008-03-31