2016-06-13 43 views
0

我有一個CSV文件的行平均:計算選定列

#col1 #col2 ... #col253 
33, 123, ... 99 
19, 409, ... 24 
34, 239, ... 60 
... ... ... .. 

和一本字典,其值存儲選定列的開始和結束索引:

d = { 
    'win': [(11, 55), (194, 233)], 
    'lose': [(72, 111), (133, 172)], 
    'neut': [(0, 10), (51, 71), (112, 132), (173, 193)] 
    } 

我的目標是計算字典中某個鍵的所有選定列的每行平均值。

例如,對於第一行的'win'塊,請選擇11, 12, ...55, 194, 195,...233列並計算平均值。

我現在使用的是什麼:

x = np.loadtxt('filename.csv', delimiter=',') 
for line in x: 
    selected = [line[start:end + 1] for (start, end) in d['win']] 
    ... 

selected[array([39, 12, 94,...]), array([3, 4, ...])]不能傳遞給np.mean()

因此,列表中的數組應該合併爲一個,我不知道如何優雅地做,或者迭代地添加所有數字,然後取平均值,我認爲這很醜。


被修改:

醜陋方法可以是:

average = sum(map(sum, selected))/sum(map(len, selected)) 
+1

您是在尋找每行的總平均值還是每行的平均值?從你的例子看,它看起來像是每行分開的意思。 –

+0

@IljaEverilä對於每一行,抱歉的描述不好。 – Spike

回答

2

numpy的陣列支持rich indexing,所以這可以例如通過切片以上的所有行和通過列表來實現要選擇的列。

爲了計算各行分別可以傳遞axis(或軸)沿着該裝置被計算作爲參數mean()

columns = np.hstack(tuple(np.arange(a, b + 1) for a, b in d['win'])) 
row_means = x[:, columns].mean(axis=1) 
+0

是的,這就是我要找的,非常感謝你,兄弟! – Spike

1

可以創建列的陣列,其覆蓋所有那些間隔編輯以向量化方式使用this other solution進行範圍。然後,將這些索引輸入到輸入數組的列x中,並計算沿第二軸(axis=1)的平均值。

讓我列舉出了量化函數來創建這樣間隔-ED的陣列在這裏再次的範圍爲方便讀者 -

def using_ones_cumsum_v2(array1, array2): 
    lens = array2 - array1 
    id_arr = np.ones(lens.sum(),dtype=array1.dtype) 
    id_arr[lens[:-1].cumsum()] = np.diff(array1) - lens[:-1]+1 
    id_arr[0] = array1[0] 
    return id_arr.cumsum() 

有了它,我們就必須爲win關鍵的平均值,像這樣 -

d_win = np.array(d['win']) 
out_win = x[:,using_ones_cumsum_v2(d_win[:,0],d_win[:,1]+1)].mean(1) 

樣品運行演示的using_ones_cumsum_v2使用以創建間隔-ED範圍 -

In [24]: d = { 
    ...:  'win': [(1, 3), (5, 8)], 
    ...:  'lose': [(2, 5), (7, 8)], 
    ...:  'neut': [(0, 1), (4, 7), (8, 9)] 
    ...:  } 

In [25]: d_win = np.array(d['win']) 

In [26]: d_win 
Out[26]: 
array([[1, 3], 
     [5, 8]]) 

In [27]: using_ones_cumsum_v2(d_win[:,0],d_win[:,1]+1) 
Out[27]: array([1, 2, 3, 5, 6, 7, 8])