2016-01-05 3 views
5

У меня есть набор данных (X, Y). Мои независимые значения переменных X не уникальны, поэтому есть несколько повторяющихся значений, я хочу вывести новый массив, содержащий: X_unique, который является списком уникальных значений X. Y_mean, среднее из всех значений Y, соответствующих X_unique , Y_std, стандартное отклонение всех значений Y, соответствующих X_unique.Выполнение сгруппированного среднего и стандартного отклонения с массивами NumPy

x = data[:,0] 
y = data[:,1] 
+1

Вы можете добавить [Minimal, полный и Проверяемость пример] (http://stackoverflow.com/help/mcve) на ваш вопрос? – Kasramvd

+0

Посмотрите http://stackoverflow.com/questions/4373631/sum-array-by-number-in-numpy –

+1

Кроме того: если вы работаете с фактическими данными, вам, вероятно, будет легче используйте ['pandas'] (http://pandas.pydata.org), чем голый numpy. Если ваши 'данные' были' DataFrame' вместо 'ndarray', то вроде' df.groupby (0) [1] .agg (["mean", "std"]) 'будет работать .. – DSM

ответ

2
x_unique = np.unique(x) 
y_means = np.array([np.mean(y[x==u]) for u in x_unique]) 
y_stds = np.array([np.std(y[x==u]) for u in x_unique]) 
4

Вы можете использовать binned_statistic from scipy.stats, который поддерживает различные статистические функции, которые будут применяться в кусках через 1D массив. Чтобы получить куски, нам нужно отсортировать и получить позиции сдвигов (при изменении кусков), для которых было бы полезно использовать np.unique. Собираем всех, вот реализация -

from scipy.stats import binned_statistic as bstat 

# Sort data corresponding to argsort of first column 
sdata = data[data[:,0].argsort()] 

# Unique col-1 elements and positions of breaks (elements are not identical) 
unq_x,breaks = np.unique(sdata[:,0],return_index=True) 
breaks = np.append(breaks,data.shape[0]) 

# Use binned statistic to get grouped average and std deviation values 
idx_range = np.arange(data.shape[0]) 
avg_y,_,_ = bstat(x=idx_range, values=sdata[:,1], statistic='mean', bins=breaks) 
std_y,_,_ = bstat(x=idx_range, values=sdata[:,1], statistic='std', bins=breaks) 

Из документов по binned_statistic, можно также использовать пользовательские функции статистики:

Функция: определяемую пользователем функцию, которая принимает массив 1D значений , и выводит одну цифровую статистику. Эта функция будет называться по значениям в каждом бункере. Пустые ячейки будут представлены функцией ([]) или NaN, если это возвращает ошибку.

вход образца, выход -

In [121]: data 
Out[121]: 
array([[2, 5], 
     [2, 2], 
     [1, 5], 
     [3, 8], 
     [0, 8], 
     [6, 7], 
     [8, 1], 
     [2, 5], 
     [6, 8], 
     [1, 8]]) 

In [122]: np.column_stack((unq_x,avg_y,std_y)) 
Out[122]: 
array([[ 0.  , 8.  , 0.  ], 
     [ 1.  , 6.5  , 1.5  ], 
     [ 2.  , 4.  , 1.41421356], 
     [ 3.  , 8.  , 0.  ], 
     [ 6.  , 7.5  , 0.5  ], 
     [ 8.  , 1.  , 0.  ]]) 
+0

Didn ' t знать о существовании 'binned_statistic'. Вероятно, я буду использовать его в ближайшем будущем! Я писал код на языке cython для достижения подобных вещей lol! благодаря! –

+0

@imaluengo Я знал, что он может получить средние значения, но я не был уверен в стандартном отклонении, и это сработало! Источником является этот ответ - http://stackoverflow.com/a/29894547/3293881. Кажется, очень аккуратно иметь что-то изначально с массивами NumPy! – Divakar

1

Панды делается для такой задачи:

data=np.random.randint(1,5,20).reshape(10,2) 
import pandas 
pandas.DataFrame(data).groupby(0).mean() 

дает

  1 
0   
1 2.666667 
2 3.000000 
3 2.000000 
4 1.500000 
Смежные вопросы