我有一个像这样的熊猫系列:
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()
答案 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