2014-08-27 3 views
3

비율을 생성 합으로 multiindex 열을 분할하고,이 비슷합니다 : 나는 multiindex 컬럼의 상위 수준 이상 반복 찾고 있어요내가 피벗 테이블에서 생성되는 dataframe이

import pandas as pd 
d = {('company1', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0}, 
('company1', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0}, 
('company1', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0}, 
('company2', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0}, 
('company2', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0}, 
('company2', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0},} 

df = pd.DataFrame(d) 

       company1 company2 
       FN FP TP FN FP TP 
April- 2012  112 0 0 112 0 0 
April- 2013  370 544 140 370 544 140 
April- 2014  499 50 24 499 50 24 
August- 2012 431 0 0 431 0 0 
August- 2013 496 0 0 496 0 0 
August- 2014 221 426 77 221 426 77 

각 회사를 그 합계로 나눠서 백분율을 만들어야합니다.

   company1  company2 
       FN FP TP FN FP TP 
April- 2012  1 0 0 1 0 0 
April- 2013  .35 .51 .13 .35 .51 .13 
April- 2014  .87 .09 .03 .87 .09 .03 
etc. 

나는 회사 이름을 미리 모릅니다. 이 질문의 변화가 어제 질문입니다 : Summing multiple columns with multiindex columns

+1

어제 답변의 결과로 나누시겠습니까? – joris

+0

네, 그게 질문입니다. 어떻게 그 일을합니까? 오류를 발생시키지 않고 줄을 긋는 방법을 알아낼 수 없습니다. – DataSwede

+0

관련 : http://stackoverflow.com/questions/13940753/aligning-dataframes-with-same-columns-different-index-levels –

답변

4
당신은 (당신이 일치하는 수준을 지정할 수 사용) div 방법을 사용 합으로 나눌 수 있습니다

:

df.div(df.sum(axis=1, level=0), level=0) 
+0

이것은 절대적으로 완벽했습니다. 다시 한 번 감사드립니다! – DataSwede

1

동안을 요리스의 작동에 의해 솔루션 멋지게, Multiindex가 더 많은 레벨을 가지 자마자 작동하지 않을 것이라고 덧붙이고 싶습니다. 다음은 StackOverflow 게시물 (Normalize DataFrame by group)과 팬더 문서 (http://pandas.pydata.org/pandas-docs/stable/groupby.html)를 부분적으로 기반으로 한 솔루션입니다.

d = { 
('X', 'company1', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0}, 
('X', 'company1', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0}, 
('X', 'company1', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0}, 
('X', 'company2', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0}, 
('X', 'company2', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0}, 
('X', 'company2', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0}, 
('Y','company1', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0}, 
('Y','company1', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0}, 
('Y','company1', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0}, 
('Y','company2', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0}, 
('Y','company2', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0}, 
('Y','company2', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0}, 
} 

df = pd.DataFrame(d) 
# extrapolation of original method: not working! 
# df.div(df.sum(axis=1,level=[0,1]), level=[0,1]) # does not work 

# alternative 1: replicating the sums for each company to fit the number of columns using numpy 
df.div(np.repeat(df.sum(axis=1,level=[0,1]).values, 3, axis=1), axis=1) 

# alternative 2: stacking, grouping, transforming and unstacking 
df.columns.names = ['top', 'company', 'result'] # naming column levels for convenience 
df.\ 
    stack(["top", "company", "result"]).\ 
    groupby(level=[0,1,2]).\ 
    transform(lambda x: (x/x.sum(axis=0))).\ 
    unstack(["top", "company", "result"]) 
관련 문제