2014-10-29 30 views
1

我有一個m-by-n的NumPy數組A,其中每行表示一些數據的觀察結果。我的行也被分配到c類之一,並且每行的類存儲在一個m乘1的NumPy數組B中。我現在想要爲每個類別計算平均觀測數據M。我怎樣才能做到這一點?通過對行進行分組來計算NumPy數組的手段

例如:

A = numpy.array([[1, 2, 3], [1, 2, 3], [3, 4, 5], [4, 5, 6]]) 
B = numpy.array([1, 0, 0, 1]) # the first row is class 1, the second row is class 0 ... 
M = # Do something 

這應該給我的輸出:

>>M 
numpy.array([[2, 3, 4], [2.5, 3.5, 4.5]]) 

在這裏,排在iMi類的平均值。

+2

你是否正在使用'numpy'?處理數據和觀察更多的是[pandas'](http://pandas.pydata.org)問題;計算手段(以及其他統計數據)是一個單線。 – DSM 2014-10-29 15:55:49

回答

3

正如在評論中提到的,取決於你想在哪裏使用它,熊貓可能更有用。但現在這仍然是可能的numpy的

import numpy 
A = numpy.array([[1, 2, 3], [1, 2, 3], [3, 4, 5], [4, 5, 6]]) 
B = numpy.array([1, 0, 0, 1]) 

class_indicators = B[:, numpy.newaxis] == numpy.unique(B) 
mean_operator = numpy.linalg.pinv(class_indicators.astype(float)) 

means = mean_operator.dot(A) 

此示例爲很多類等,但正如你看到的,這可能是麻煩的

2

另一種方式來做到這一點使用numpy的新at功能。

A = numpy.array([[1, 2, 3], [1, 2, 3], [3, 4, 5], [4, 5, 6]]) 
B = numpy.array([1, 0, 0, 1]) 

u, uinds = numpy.unique(B, return_inverse=True) 
M = numpy.zeros((u.shape[0], A.shape[-1])) 
numpy.add.at(M, B, A) 
M /= numpy.bincount(uinds)[:, None] 

M 
array([[ 2. , 3. , 4. ], 
     [ 2.5, 3.5, 4.5]]) 

如前所述大熊貓將使它更容易些:

import pandas as pd 

>>> pd.DataFrame(A).groupby(B).mean() 
    0 1 2 
0 2.0 3.0 4.0 
1 2.5 3.5 4.5 
+0

我喜歡'add.at'!但是'M [B] + = A'不應該與一個索引數組一起工作,因爲索引創建了一個副本,並且這個增加被它吞噬了。 – eickenberg 2014-10-29 16:26:08

+1

嗯,你是對的,我認爲其中一個測試版結合了功能。仔細閱讀文檔表明,這是有意的,謝謝你指出這一點。 – Daniel 2014-10-29 16:36:33

+0

在任何情況下,爲'add.at' +1,我真的學到了一些東西! – eickenberg 2014-10-29 16:46:10

0

這是一個典型的分組問題,它可以在一個單一的線使用numpy_indexed包來解決(免責聲明:我是它的作者):

import numpy_indexed as npi 
npi.group_by(B).mean(A) 
相關問題