2014-10-23 23 views
15

Tôi đã đọc tệp csv và xoay quanh nó để đi đến cấu trúc sau.Pandas tổng các cột và chia mỗi ô từ giá trị đó

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) 

Mục của kết quả:

   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 

Tôi muốn tổng hợp trên cột từ 0 đến cột 13 của mỗi hàng và phân chia mỗi tế bào bằng tổng của hàng đó. Tôi vẫn quen với gấu trúc, Nếu tôi hiểu chính xác, chúng ta nên cố tránh những vòng lặp khi làm những việc như thế này? Vì vậy, làm thế nào tôi có thể làm theo cách này gấu trúc?

+0

tôi t hink như vậy, đi nhiều sudo: '0/sum (0..13), 1/sum (0..13)' cũng 'cột 0' là tên của cột không cần thiết chỉ mục của nó.' –

Trả lời

20

Hãy thử như sau:

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 

Hoặc bạn có thể làm như sau:

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 

Hoặc chỉ thẳng lên từ đầu:

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 

Thay đổi cột value1 và tương tự như tiêu đề của bạn sẽ hoạt động tương tự.

2

Sau đây dường như làm việc tốt cho tôi:

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 trầy xước ở trên, sau đây sẽ được nhanh hơn nhiều:

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

Và chỉ để chứng minh kết quả là như nhau:

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 

Và nó nhanh hơn:

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

xin lỗi tôi muốn tổng hợp nó cho đến cột 13. có một lỗi đánh máy. –

+1

@ Null-Giả thuyết câu trả lời ban đầu của tôi là không chính xác, đã sửa chữa nó ngay bây giờ, bây giờ tôi áp dụng hàng khôn ngoan chia từng mục bằng tổng hàng, các giá trị có vẻ đúng với tôi bây giờ – EdChum

+0

mà không làm điều này không có cách nào khác để đề cập đến tất cả các cột 'cols = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11 ', '12', '13'] '× Nhận xét chỉ có thể được chỉnh sửa trong 5 phút × Bình luận chỉ có thể được chỉnh sửa trong 5 phút × Bình luận chỉ có thể được chỉnh sửa trong 5 phút –

14

More đơn giản:

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

(Edited để sử dụng mã nổi bật)

4

dễ dàng hơn để làm việc mỗi cột:

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

kết quả:

  0   1  2 
0 0.166667 0.333333 0.500 
1 0.266667 0.333333 0.400 
2 0.291667 0.333333 0.375 
Các vấn đề liên quan