我有一个典型的"面板数据" (在计量经济学术语中,不是熊猫面板对象)。数据框包含Date
列和ID
列,以及包含特定值的其他列。对于每个日期,我需要将基于V1的ID横截面排列为10组(十分位数),并创建一个名为rank_col
的新列(取值1到10)以识别排名。然后将所有rank1,rank2,... rank10汇集在一起以获得一些统计数据,如mean,std。
这可以通过以下代码在SAS中轻松完成,它还说明了我的目的:
proc sort data=df;
by Date;
proc rank data=df out=df_ranked groups=10;
var V1;
ranks rank_col;
by Date;
run;
df_ranked
与df
相同,只是它有更多名为rank_col
的列,其中包含每行所属的排名组。
抱歉,我没有显示结构的示例数据,需要一个真实的长数据来说明。但SAS代码正好显示了我的目标。
感谢您的帮助!
答案 0 :(得分:5)
我发现的一种方法:
def grouping(data):
dec=pd.qcut(data['V1'],10,labels=False)
data['ranks']=dec
return data
df_ranked=df.groupby('Date').apply(grouping)
这假定dec
保留每行的正确位置。
如果您有更好的方法,请发布,或指出此方法中的任何错误。
谢谢!
修改:如果您执行以下操作,则只需返回一个新的ranks
列:
>>> df
Date id V1
0 2013-01-01 1 10
1 2013-01-01 2 8
2 2013-01-01 3 6
3 2013-01-01 4 11
4 2013-01-01 5 13
5 2013-01-01 6 4
6 2013-01-01 7 2
7 2013-02-01 1 1
8 2013-02-01 2 3
9 2013-02-01 3 9
10 2013-02-01 4 11
11 2013-02-01 5 7
12 2013-02-01 6 4
13 2013-02-01 7 6
14 2013-02-01 8 14
>>> foo = lambda x: pd.Series(pd.qcut(x,10,labels=False),index=x.index)
>>> df['ranks'] = df.groupby('Date')['V1'].apply(foo)
>>> df
Date id V1 ranks
0 2013-01-01 1 10 6
1 2013-01-01 2 8 4
2 2013-01-01 3 6 3
3 2013-01-01 4 11 8
4 2013-01-01 5 13 9
5 2013-01-01 6 4 1
6 2013-01-01 7 2 0
7 2013-02-01 1 1 0
8 2013-02-01 2 3 1
9 2013-02-01 3 9 7
10 2013-02-01 4 11 8
11 2013-02-01 5 7 5
12 2013-02-01 6 4 2
13 2013-02-01 7 6 4
14 2013-02-01 8 14 9
答案 1 :(得分:0)
如果不需要单独的foo,它可能更简单
In [782]: df.groupby('Date')['V1'].transform(lambda x: pd.qcut(x, 10, labels=False))
Out[782]:
0 6
1 4
2 3
3 8
4 9
5 1
6 0
7 0
8 1
9 7
10 8
11 5
12 2
13 4
14 9
Name: V1, dtype: int64
分配到列
In [783]: df['ranks'] = df.groupby('Date')['V1'].transform(pd.qcut, 10, labels=False)
In [784]: df
Out[784]:
Date id V1 ranks
0 2013-01-01 1 10 6
1 2013-01-01 2 8 4
2 2013-01-01 3 6 3
3 2013-01-01 4 11 8
4 2013-01-01 5 13 9
5 2013-01-01 6 4 1
6 2013-01-01 7 2 0
7 2013-02-01 1 1 0
8 2013-02-01 2 3 1
9 2013-02-01 3 9 7
10 2013-02-01 4 11 8
11 2013-02-01 5 7 5
12 2013-02-01 6 4 2
13 2013-02-01 7 6 4
14 2013-02-01 8 14 9
详细
In [786]: df
Out[786]:
Date id V1
0 2013-01-01 1 10
1 2013-01-01 2 8
2 2013-01-01 3 6
3 2013-01-01 4 11
4 2013-01-01 5 13
5 2013-01-01 6 4
6 2013-01-01 7 2
7 2013-02-01 1 1
8 2013-02-01 2 3
9 2013-02-01 3 9
10 2013-02-01 4 11
11 2013-02-01 5 7
12 2013-02-01 6 4
13 2013-02-01 7 6
14 2013-02-01 8 14