Écart-type pondéré de NumPy?

numpy.average() a une option de poids, mais numpy.std() n'en a pas. Est-ce que quelqu'un a des suggestions pour une solution de contournement?

56
demandé sur JohnE 2010-03-10 02:53:36

5 réponses

court "manuel de calcul"?

def weighted_avg_and_std(values, weights):
    """
    Return the weighted average and standard deviation.

    values, weights -- Numpy ndarrays with the same shape.
    """
    average = numpy.average(values, weights=weights)
    # Fast and numerically precise:
    variance = numpy.average((values-average)**2, weights=weights)
    return (average, math.sqrt(variance))
90
répondu Eric Lebigot 2018-10-11 10:31:18

il y a une classe dans statsmodels pour calculer les statistiques pondérées: statsmodels.stats.weightstats.DescrStatsW :

from statsmodels.stats.weightstats import DescrStatsW

array = np.array([1,2,1,2,1,2,1,3])
weights = np.ones_like(array)
weights[3] = 100

weighted_stats = DescrStatsW(array, weights=weights, ddof=0)

weighted_stats.mean      # weighted mean of data (equivalent to np.average(array, weights=weights))
# 1.97196261682243

weighted_stats.std       # standard deviation with default degrees of freedom correction
# 0.21434289609681711

weighted_stats.std_mean  # standard deviation of weighted mean
# 0.020818822467555047

weighted_stats.var       # variance with default degrees of freedom correction
# 0.045942877107170932

la caractéristique agréable de cette classe est que si vous voulez calculer des propriétés statistiques différentes, les appels suivants seront très rapides car les résultats déjà calculés (même intermédiaires) sont mis en cache.

20
répondu MSeifert 2018-02-28 19:49:07

il ne semble pas y avoir une telle fonction dans numpy/scipy encore, mais il y a un ticket proposant cette fonctionnalité ajoutée. Vous y trouverez Statistics.py , qui met en œuvre les écarts-types pondérés.

6
répondu unutbu 2016-03-15 04:07:40

il y a un très bon exemple proposé par gaborous :

import pandas as pd
import numpy as np
# X is the dataset, as a Pandas' DataFrame
mean = mean = np.ma.average(X, axis=0, weights=weights) # Computing the 
weighted sample mean (fast, efficient and precise)

# Convert to a Pandas' Series (it's just aesthetic and more 
# ergonomic; no difference in computed values)
mean = pd.Series(mean, index=list(X.keys())) 
xm = X-mean # xm = X diff to mean
xm = xm.fillna(0) # fill NaN with 0 (because anyway a variance of 0 is 
just void, but at least it keeps the other covariance's values computed 
correctly))
sigma2 = 1./(w.sum()-1) * xm.mul(w, axis=0).T.dot(xm); # Compute the 
unbiased weighted sample covariance

Corriger l'équation pondérée impartiale échantillon de covariance, URL (version: 2016-06-28)

1
répondu abah 2017-11-29 21:55:48

Voici une autre option:

np.sqrt(np.cov(values, aweights=weights))
0
répondu Leo 2018-10-04 21:15:38