2016-01-05 14 views
5

Ho un set di dati (X, Y). I miei valori variabili indipendenti X non sono univoci, quindi ci sono più valori ripetuti, voglio produrre un nuovo array contenente: X_unique, che è un elenco di valori univoci di X. Y_mean, la media di tutti i valori Y corrispondenti a X_unique . Y_std, la deviazione standard di tutti i valori Y corrispondenti a X_unique.Esecuzione della media raggruppata e deviazione standard con gli array NumPy

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

è possibile aggiungere un [Minimal, completa e verificabile esempio] (http://stackoverflow.com/help/mcve) alla tua domanda? – Kasramvd

+0

Dai un'occhiata a http://stackoverflow.com/questions/4373631/sum-array-by-number-in-numpy –

+1

A parte questo: se stai lavorando con dati reali, probabilmente troverai più facile usa ['pandas'] (http://pandas.pydata.org) piuttosto che numpy. Se il tuo 'data' era un' DataFrame' invece di un 'ndarray', qualcosa come' df.groupby (0) [1] .agg (["mean", "std"]) 'funzionerebbe .. – DSM

risposta

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

È possibile utilizzare binned_statistic from scipy.stats che supporta vari funzioni statistiche che devono essere applicati in blocchi attraverso una matrice 1D. Per ottenere i pezzi, abbiamo bisogno di ordinare e ottenere posizioni dei turni (dove cambiano i pezzi), per cui np.unique sarebbe utile. Mettendo tutti coloro, ecco un'implementazione -

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) 

Dalla documentazione di binned_statistic, si può anche usare una funzione statistica personalizzata:

funzione: una funzione definita dall'utente che richiede una matrice 1D di valori , e genera una singola statistica numerica. Questa funzione si chiamerà sui valori in ciascun cestino. I contenitori vuoti saranno rappresentati dalla funzione ([]), o NaN se questo restituisce un errore.

di ingresso del campione, in uscita -

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 ' so dell'esistenza di 'binned_statistic'. Probabilmente lo userò molto nel prossimo futuro! Stavo scrivendo codice cython per ottenere cose simili lol! Grazie! –

+0

@imaluengo Sapevo che poteva ottenere valori medi, ma non ero sicuro della deviazione standard, e ha funzionato! La fonte è questa risposta: http://stackoverflow.com/a/29894547/3293881. Sembra davvero bello avere qualcosa in modo nativo con gli array di NumPy! – Divakar

1

Panda è fatto per tale compito:

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 
Problemi correlati