2016-06-13 4 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

Вы можете создать массив столбцов, который охватывает все те interval-ed диапазонов в векторизованном порядке с использованием this other solution. Затем проиндексируйте в столбцы входного массива, x с теми, и вычислите среднее по второй оси (axis=1).

Позволь мне перечислить векторизованную функцию, чтобы создать массив такого интервала-й изд диапазонов снова здесь для удобства читателей -

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) 

Sample прогон, чтобы продемонстрировать использование using_ones_cumsum_v2 для создания интервальным ред диапазонов -

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]) 
Смежные вопросы