2014-10-23 3 views
15

저는 csv 파일을 읽고 다음 구조로 피벗했습니다. 결과팬더는 열을 가로 질러 합계하고 그 값에서 각 셀을 나눕니다.

pivoted = df.pivot('user_id', 'group', 'value') 
lookup = df.drop_duplicates('user_id')[['user_id', 'group']] 
lookup.set_index(['user_id'], inplace=True) 
result = pivoted.join(lookup) 
result = result.fillna(0) 

부분 :

I는 각 행에서 열 (13)에 열 0 걸쳐 합산하고, 그 행의 합으로 각각의 셀 분할 할
   0  1  2 3  4 5 6 7 8 9 10 11 12 13 group 
user_id                  
2  33653 2325 916 720 867 187 31 0 6 3 42 56 92 15 l-1 
4  18895 414 1116 570 1190 55 92 0 122 23 78 6 4 2 l-2 
16  1383 70 27 17 17 1 0 0 0 0 1 0 0 0 l-2 
50   396 72 34 5 18 0 0 0 0 0 0 0 0 0 l-3 
51  3915 1170 402 832 2791 316 12 5 118 51 32 9 62 27 l-4 

. 나는 팬더에 익숙해 져 있습니다. 올바르게 이해한다면, 이런 일을 할 때 루프를 피하려고 노력해야합니다. 그렇다면이 팬더를 어떻게 할 수 있습니까?

+0

I t을 (0,13), 1/sum (0..13)'또한'column 0'은 인덱스가 필요없는 컬럼의 이름이다.' –

답변

20

다음을 시도해보십시오 :

In [1]: import pandas as pd 

In [2]: df = pd.read_csv("test.csv") 

In [3]: df 
Out[3]: 
    id value1 value2 value3 
0 A  1  2  3 
1 B  4  5  6 
2 C  7  8  9 

In [4]: df["sum"] = df.sum(axis=1) 

In [5]: df 
Out[5]: 
    id value1 value2 value3 sum 
0 A  1  2  3 6 
1 B  4  5  6 15 
2 C  7  8  9 24 

In [6]: df_new = df.loc[:,"value1":"value3"].div(df["sum"], axis=0) 

In [7]: df_new 
Out[7]: 
    value1 value2 value3 
0 0.166667 0.333333 0.500 
1 0.266667 0.333333 0.400 
2 0.291667 0.333333 0.375 

아니면 다음을 수행 할 수 있습니다

In [8]: df.loc[:,"value1":"value3"] = df.loc[:,"value1":"value3"].div(df["sum"], axis=0) 

In [9]: df 
Out[9]: 
    id value1 value2 value3 sum 
0 A 0.166667 0.333333 0.500 6 
1 B 0.266667 0.333333 0.400 15 
2 C 0.291667 0.333333 0.375 24 

아니면 그냥 똑바로 처음부터 : 열을 변경

In [10]: df = pd.read_csv("test.csv") 

In [11]: df 
Out[11]: 
    id value1 value2 value3 
0 A  1  2  3 
1 B  4  5  6 
2 C  7  8  9 

In [12]: df.loc[:,"value1":"value3"] = df.loc[:,"value1":"value3"].div(df.sum(axis=1), axis=0) 

In [13]: df 
Out[13]: 
    id value1 value2 value3 
0 A 0.166667 0.333333 0.500 
1 B 0.266667 0.333333 0.400 
2 C 0.291667 0.333333 0.375 

value1 및 헤더와 비슷하게 비슷하게 작동해야합니다. 단순히

2

다음은 나를 위해 잘 작동하는 것 같았다 :

In [39]: 

cols = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13'] 
result[cols] = result[cols].apply(lambda row: row/row.sum(axis=1), axis=1) 
result 

Out[39]: 
       0   1   2   3   4   5   6 \ 
user_id                   
2  0.864827 0.059749 0.023540 0.018503 0.022280 0.004806 0.000797 
4  0.837285 0.018345 0.049453 0.025258 0.052732 0.002437 0.004077 
16  0.912269 0.046174 0.017810 0.011214 0.011214 0.000660 0.000000 
50  0.754286 0.137143 0.064762 0.009524 0.034286 0.000000 0.000000 
51  0.401868 0.120099 0.041265 0.085403 0.286491 0.032437 0.0

       7   8   9  10  11  12  13 \ 
user_id                   
2  0.000000 0.000154 0.000077 0.001079 0.001439 0.002364 0.000385 
4  0.000000 0.005406 0.001019 0.003456 0.000266 0.000177 0.000089 
16  0.000000 0.000000 0.000000 0.000660 0.000000 0.000000 0.000000 
50  0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 
51  0.000513 0.012113 0.005235 0.003285 0.000924 0.006364 0.002772 

     group 
user_id   
2   l-1 
4   l-2 
16  l-2 
50  l-3 
51  l-4 

OK 스크래치를 위, 아래가 훨씬 더 빨리 될 것입니다 :

result[cols] = result[cols].div(result[cols].sum(axis=1), axis=0) 

그리고 바로 결과를 증명하는 것은 동일합니다

In [47]: 

cols = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13'] 
np.alltrue(result[cols].div(result[cols].sum(axis=1), axis=0) == result[cols].apply(lambda row: row/row.sum(axis=1), axis=1)) 
Out[47]: 
True 

그리고 있다는 빨리 :

In [48]: 

cols = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13'] 
%timeit result[cols].div(result[cols].sum(axis=1), axis=0) 
%timeit result[cols].apply(lambda row: row/row.sum(axis=1), axis=1) 
100 loops, best of 3: 2.38 ms per loop 
100 loops, best of 3: 4.47 ms per loop 
+0

미안하다. 열 13까지 줄을 써라. 오타가 있었다. –

+1

@ Null-Hypothesis 원래 답이 잘못되어 지금 바로 수정했습니다. 이제 각 항목을 행 합계로 나누어 적용합니다. 이제는 값이 정확합니다. – EdChum

+0

이 작업을 수행하지 않고 모든 열을 언급 할 수있는 방법이 없습니다. 'cols = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11 ', '12', '13']'× 코멘트는 5 분간 만 편집 가능 × 코멘트는 5 분간 편집 가능 × 코멘트는 5 분간 만 편집 가능 –

14

더 :

result.div(result.sum(axis=1), axis=0)

(사용하는 편집 코드를 강조)

4

열마다 작동하기 쉬운 :

df = pd.DataFrame([[1,2,3],[4,5,6],[7,8,9]]) 
(df.T/df.T.sum()).T 

결과 :

  0   1  2 
0 0.166667 0.333333 0.500 
1 0.266667 0.333333 0.400 
2 0.291667 0.333333 0.375