2017-06-21 20 views
1

透视表:如何使用不同的索引比较pandas pivot_table中的值?

COURSE   ENGLISH  MATH  ART 
STUDENT    

StudentA  95.0   83.0  97.0 
StudentB  91.0   93.0  47.0 
StudentC  85.0   84.0  92.0 
StudentD  97.0   84.0  85.0 
StudentE  93.0   88.0  85.0 
StudentAvg  94.5   83.7  96.9 

我想谁拥有一个档次比StudentAvg按主题超过5%下的学生名单。因此,在这种情况下,我想要的东西,如:

English: StudentC Math: Art: StudentB, StudentD, StudentE

我怎样才能做到这一点的熊猫吗?

回答

2

这返回一个元组列表,显示哪个学生和哪个科目的成绩比平均值低5%以上。

avg = df.loc['StudentAvg', :] 
i, j = np.where(((df/avg) - 1) < -.05) 
list(zip(df.index[i], df.columns[j])) 

[('StudentB', 'ART'), 
('StudentC', 'ENGLISH'), 
('StudentC', 'ART'), 
('StudentD', 'ART'), 
('StudentE', 'ART')] 

我们能不更加清晰之前,我加快了一下有

p = df.index.get_loc('StudentAvg') 
v = df.values 
i, j = np.where(((v/v[p]) - 1) < -.05) 
list(zip(df.index[i], df.columns[j])) 

[('StudentB', 'ART'), 
('StudentC', 'ENGLISH'), 
('StudentC', 'ART'), 
('StudentD', 'ART'), 
('StudentE', 'ART')] 

定时

%%timeit 
p = df.index.get_loc('StudentAvg') 
v = df.values 
i, j = np.where(((v/v[p]) - 1) < -.05) 
list(zip(df.index[i], df.columns[j])) 
10000 loops, best of 3: 41.7 µs per loop 

%%timeit 
avg = df.loc['StudentAvg', :] 
i, j = np.where(((df/avg) - 1) < -.05) 
list(zip(df.index[i], df.columns[j]))\ 
1000 loops, best of 3: 662 µs per loop 
+0

你是否告诉我分别计算了417秒和662秒?或者你的意思是你做了10000次迭代,而那些是最好的平均值? –

+1

@NishantRoy不! 41.7微秒和662微秒 – piRSquared

+0

41.7微秒为整个代码块运行,对不对?或者你是说每循环多少时间,代码块需要10,000个循环。 –

1

编辑:

df.apply(lambda x: str(x.name)+ ': ' + ', '.join(df[((x-x.loc['StudentAvg'])/x.loc['StudentAvg']*100<-5.0)].index.tolist())).values.tolist() 

输出:

['ENGLISH: StudentC', 'MATH: ', 'ART: StudentB, StudentC, StudentD, StudentE'] 

让我们用这样的:

mask = df.apply(lambda x: (x-x.loc['StudentAvg'])/x.loc['StudentAvg']*100<-5.0).any(axis=1) 
df[mask].index.tolist() 

输出:

['StudentB', 'StudentC', 'StudentD', 'StudentE'] 
+0

对不起。我想通过'Subject'获取一个列表,只是在帖子中添加了一个示例。你能修改你的答案吗? –

+1

@NishantRoy我修改了解决方案。 –

相关问题