2015-07-12 39 views
6

Cách hiệu quả nhất để tuần tự tìm thấy trung bình và trung bình của các hàng trong danh sách Python là gì?Tính trung bình và trung bình hiệu quả

Ví dụ, danh sách của tôi:

input_list = [1,2,4,6,7,8] 

Tôi muốn tạo ra một danh sách kết quả có chứa:

output_list_mean = [1,1.5,2.3,3.25,4,4.7] 
output_list_median = [1,1.5,2.0,3.0,4.0,5.0] 

đâu giá trị trung bình được tính như sau:

  • 1 = nghĩa là (1)
  • 1.5 = trung bình (1,2) (nghĩa là giá trị trung bình của 2 giá trị đầu tiên trong input_list)
  • 2.3 = trung bình (1,2,4) (tức là nghĩa của 3 giá trị đầu tiên trong input_list)
  • 3,25 = trung bình (1,2,4,6) (tức là nghĩa của 4 giá trị đầu tiên trong input_list) , vv

Và trung bình được tính như sau:

  • 1 = trung bình (1)
  • 1,5 = trung bình (1,2) (tức là trung bình của 2 giá trị đầu tiên trong input_list)
  • 2,0 = trung bình (1,2,4) (tức là trung bình 3 giá trị đầu tiên trong input_list)
  • 3.0 = trung bình (1,2,4,6) (tức là trung bình của 4 giá trị đầu tiên trong input_list) v.v.

Tôi đã cố gắng thực hiện nó với vòng lặp sau, nhưng có vẻ như rất kém hiệu quả.

import numpy 

input_list = [1,2,4,6,7,8] 

for item in range(1,len(input_list)+1): 
    print(numpy.mean(input_list[:item])) 
    print(numpy.median(input_list[:item])) 
+0

"có vẻ rất không hiệu quả" so với những gì? Bạn có thời gian không? Tôi nghi ngờ 'import numpy' thống trị thời gian chạy (và bạn không cần nó) – msw

Trả lời

4

Bạn có thể sử dụng itertools.islice để cắt mảng của bạn và sử dụng np.fromiter với np.mean:

>>> arr=np.array([1,2,4,6,7,8]) 
>>> l=arr.size 
>>> from itertools import islice 
>>> [np.fromiter(islice(arr,0,i+1),float).mean(dtype=np.float32) for i in xrange(l)] 
[1.0, 1.5, 2.3333333, 3.25, 4.0, 4.6666665] 

Như một câu trả lời thay thế bạn nếu bạn muốn với mức trung bình bạn có thể sử dụng np.cumsum để có được một khoản tiền tích lũy của bạn các phần tử và chia cho mảng chính bằng cách sử dụng np.true_divide:

>>> np.true_divide(np.cumsum(arr),arr) 
array([ 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4.5]) 
+0

Cảm ơn @Kasra! Tôi có thể sử dụng np để tìm trung bình tuần tự không? –

+0

@hoof_hearted Chào mừng bạn! xin lỗi ý bạn là gì * trung bình tuần tự *? – Kasramvd

+0

Như trong, tôi cần tìm giá trị trung bình của giá trị đầu tiên (1), hai giá trị đầu tiên (1,2), ba giá trị đầu tiên (1,2,3) v.v. Đầu ra sẽ giống nhau trong ví dụ này (tức là output_list = [1,1,5,2,2,5,3,3,5,4,4,5]), nhưng tôi tính giá trị trung bình của tất cả các giá trị, trái ngược với giá trị trung bình. Tôi hy vọng điều đó rõ ràng là –

8

Bất kỳ điều bạn làm, đặc biệt là với trung bình, hoặc sẽ yêu cầu rất nhiều công việc, hoặc rất kém hiệu quả, nhưng Pandas đi kèm với việc triển khai hiệu quả các chức năng bạn đang có, ý nghĩa mở rộng là O (n), trung bình mở rộng là O (n * log (n)) sử dụng một danh sách bỏ qua:

import pandas as pd 
import numpy as np 

input_list = [1, 2, 4, 6, 7, 8] 

>>> pd.expanding_mean(np.array(input_list)) 
array([ 1.  , 1.5 , 2.33333, 3.25 , 4.  , 4.66667]) 

>>> pd.expanding_median(np.array(input_list)) 
array([ 1. , 1.5, 2. , 3. , 4. , 5. ]) 
0
import numpy as np 
a = np.array([1,2,4,6,7,8]) 

sử dụng numpy.meshgrid (có công thức khác mà làm việc) và numpy.triu để tạo ra một mảng với những giá trị mà bạn quan tâm in.

x, y = np.meshgrid(a,a) 
# y = a.repeat(len(a)).reshape(len(a), len(a)) 
c = np.triu(y) 

>>> y 
array([[1, 1, 1, 1, 1, 1], 
     [2, 2, 2, 2, 2, 2], 
     [4, 4, 4, 4, 4, 4], 
     [6, 6, 6, 6, 6, 6], 
     [7, 7, 7, 7, 7, 7], 
     [8, 8, 8, 8, 8, 8]]) 
>>> c 
array([[1, 1, 1, 1, 1, 1], 
     [0, 2, 2, 2, 2, 2], 
     [0, 0, 4, 4, 4, 4], 
     [0, 0, 0, 6, 6, 6], 
     [0, 0, 0, 0, 7, 7], 
     [0, 0, 0, 0, 0, 8]]) 

Xác định hàm trả về giá trị trung bình của tất cả các giá trị khác 0 và áp dụng nó cho mảng thú vị của bạn.

def foo(a): 
    '''return the the median of the non-zero elements of a 1d array 
    ''' 
    return np.median(a[a.nonzero()]) 
d = np.apply_along_axis(foo, 0, c) 

>>> d 
array([ 1. , 1.5, 2. , 3. , 4. , 5. ]) 
>>> 
Các vấn đề liên quan