2014-10-23 5 views
15

Przeczytałem plik csv i obróciłem go, aby uzyskać następującą strukturę.Pandy sumują się w kolumnach i dzielą każdą komórkę od tej wartości.

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) 

Sekcja wyniku:

   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 

Chcę podsumować całej kolumny 0 do kolumny 13 przez każdego wiersza i podzielić każdą komórkę przez sumę tym wierszu. Nadal przyzwyczajam się do pandy. Jeśli dobrze rozumiem, powinniśmy starać się unikać pętli podczas robienia takich rzeczy? Więc jak mogę zrobić ten pandowy sposób?

+0

I t Hink tak, idąc więcej sudo: '0/suma (0..13), 1/suma (0..13)' również 'kolumna 0' jest nazwą kolumny nie jest konieczne jej indeks. " –

Odpowiedz

20

Spróbuj wykonać następujące czynności:

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 

Albo można wykonać następujące czynności:

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 

Albo po prostu prosto od początku:

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 

Zmiana kolumnę value1 i podobne do nagłówków powinny działać podobnie.

2

Poniższa wydawało się działać dobrze dla mnie:

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 zarysować powyżej dodaje będzie znacznie szybciej:

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

I właśnie udowodnić rezultat jest taki sam:

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 

i że jest to szybsze:

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

Przepraszam, chciałem sumuj to aż do kolumny 13. był literówka. –

+1

@ Null-Hypothesis moja oryginalna odpowiedź była niepoprawna, poprawiłem ją teraz, teraz stosuję szeregowy podział każdej pozycji przez sumę wierszy, wartości wydają mi się teraz poprawne – EdChum

+0

bez robienia tego nie ma innego sposobu na wymienienie wszystkich kolumn 'cols = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11 ', '12', '13'] '× Komentarze mogą być edytowane tylko przez 5 minut × Komentarze mogą być edytowane tylko przez 5 minut × Komentarze mogą być edytowane tylko przez 5 minut –

14

Mówiąc prościej:

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

(Zmieniano używać kodu podświetlania)

4

łatwiej pracować na kolumnie:

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

Wynik:

  0   1  2 
0 0.166667 0.333333 0.500 
1 0.266667 0.333333 0.400 
2 0.291667 0.333333 0.375 
Powiązane problemy