您是否可以帮助我为此问题找到更好的解决方案,如下所示: 对于每个日期(在列中),我有值。我对它们进行排名并分为三组。我的目标是按低,中,上组对值进行分组,并计算组均值。我把DataFrame和我自己的解决方案放在下面。 有谁能建议更好的解决方案? 我的真实数据有10000行和300列。 任何申请或lambda方式更直接地做?谢谢。
value=DataFrame({'1/1/2000':[1,4,5,6,5],
'1/1/2001':[3,7,8,9,4],
'1/1/2002':[7,8,9,4,5]}, index=list('ABCDE'))
rank=value.apply(lambda x: pd.qcut(x, 3, labels=['low','mid','top']))
df=pd.DataFrame()
df['Value']=value.stack()
df['Rank']=rank.stack()
df1=df.reset_index()
df1.groupby(['Date','Rank']).mean()
答案 0 :(得分:1)
您只能使用一个stack
,然后pd.qcut
只能使用一列Value
而不是DataFrame
:
df = value.stack()
.reset_index(name='Value')
.rename(columns={'level_0':'Type','level_1':'Date'})
df['Rank'] = pd.qcut(df.Value, 3, labels=['low','mid','top'])
print (df)
Type Date Value Rank
0 A 1/1/2000 1 low
1 A 1/1/2001 3 low
2 A 1/1/2002 7 mid
3 B 1/1/2000 4 low
4 B 1/1/2001 7 mid
5 B 1/1/2002 8 top
6 C 1/1/2000 5 mid
7 C 1/1/2001 8 top
8 C 1/1/2002 9 top
9 D 1/1/2000 6 mid
10 D 1/1/2001 9 top
11 D 1/1/2002 4 low
12 E 1/1/2000 5 mid
13 E 1/1/2001 4 low
14 E 1/1/2002 5 mid
print (df.groupby(['Date','Rank'])['Value'].mean())
Date Rank
1/1/2000 low 2.500000
mid 5.333333
1/1/2001 low 3.500000
mid 7.000000
top 8.500000
1/1/2002 low 4.000000
mid 6.000000
top 8.500000
Name: Value, dtype: float64
print (df.groupby(['Date','Rank'])['Value'].mean().reset_index(name='Value'))
Date Rank Value
0 1/1/2000 low 2.500000
1 1/1/2000 mid 5.333333
2 1/1/2001 low 3.500000
3 1/1/2001 mid 7.000000
4 1/1/2001 top 8.500000
5 1/1/2002 low 4.000000
6 1/1/2002 mid 6.000000
7 1/1/2002 top 8.500000
编辑:
您也可以省略创建新列Rank
并将其传递给groupby
:
df = value.stack()
.reset_index(name='Rank')
.rename(columns={'level_0':'Type','level_1':'Date'})
print (df)
Type Date Rank
0 A 1/1/2000 1
1 A 1/1/2001 3
2 A 1/1/2002 7
3 B 1/1/2000 4
4 B 1/1/2001 7
5 B 1/1/2002 8
6 C 1/1/2000 5
7 C 1/1/2001 8
8 C 1/1/2002 9
9 D 1/1/2000 6
10 D 1/1/2001 9
11 D 1/1/2002 4
12 E 1/1/2000 5
13 E 1/1/2001 4
14 E 1/1/2002 5
print (df['Rank'].groupby([df.Date,
pd.qcut(df.Rank, 3, labels=['low','mid','top'])])
.mean().reset_index(name='Value'))
Date Rank Value
0 1/1/2000 low 2.500000
1 1/1/2000 mid 5.333333
2 1/1/2001 low 3.500000
3 1/1/2001 mid 7.000000
4 1/1/2001 top 8.500000
5 1/1/2002 low 4.000000
6 1/1/2002 mid 6.000000
7 1/1/2002 top 8.500000