복붙노트

[PYTHON] 팬더는 열을 가로 질러 합계를하고 그 값에서 각 셀을 나눕니다.

PYTHON

팬더는 열을 가로 질러 합계를하고 그 값에서 각 셀을 나눕니다.

나는 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) 

결과의 섹션 :

             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에서 열 13까지를 합하여 각 셀을 해당 행의 합으로 나누고 싶습니다. 나는 아직도 팬더에 익숙해있다. 만약 내가 올바르게 이해한다면, 우리는 이런 일을 할 때 루프를 피하려고 노력해야합니다. 즉, 어떻게 '팬더'방식으로이 작업을 수행 할 수 있습니까?

해결법

  1. ==============================

    1.다음을 시도하십시오.

    다음을 시도하십시오.

    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
    

    열 값 1 등을 헤더로 변경하면 비슷하게 작동합니다.

  2. ==============================

    2.더 간단하게 :

    더 간단하게 :

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

    (코드 하이라이트를 사용하도록 편집 됨)

  3. ==============================

    3.컬럼 당 더 쉽게 작업 할 수 있습니다.

    컬럼 당 더 쉽게 작업 할 수 있습니다.

    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
    
  4. ==============================

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

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

    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.001232   
    
                    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
    
  5. from https://stackoverflow.com/questions/26537878/pandas-sum-across-columns-and-divide-each-cell-from-that-value by cc-by-sa and MIT license