web-dev-qa-db-fra.com

Que faire des valeurs manquantes lors du complot avec Seaborn?

J'ai remplacé les valeurs manquantes par NaN en utilisant la fonction suivante lambda:

data = data.applymap(lambda x: np.nan if isinstance(x, basestring) and x.isspace() else x)

, où data est le dataframe sur lequel je travaille.

En utilisant seaborn ensuite, j'ai essayé de tracer un de ses attributs, alcconsumption en utilisant seaborn.distplot comme suit:

seaborn.distplot(data['alcconsumption'],hist=True,bins=100)
plt.xlabel('AlcoholConsumption')
plt.ylabel('Frequency(normalized 0->1)')

Cela me donne l'erreur suivante:

AttributeError: max must be larger than min in range parameter.
13
datavinci

Je gérerais certainement les valeurs manquantes avant vous tracez vos données. Le fait de ne pas utiliser dropna() dépendra entièrement de la nature de votre ensemble de données. alcconsumption est-il une seule série ou une partie d'une trame de données? Dans ce dernier cas, l'utilisation de dropna() supprimerait également les lignes correspondantes dans les autres colonnes. Les valeurs manquantes sont-elles rares ou nombreuses? Sont-ils répartis dans votre série ou ont-ils tendance à se produire en groupe? Y a-t-il peut-être des raisons de croire qu'il existe une tendance dans votre ensemble de données?

Si les valeurs manquantes sont peu nombreuses et dispersées, vous pouvez facilement utiliser dropna (). Dans d'autres cas, je choisirais de remplir les valeurs manquantes avec la valeur précédemment observée (1). Ou même remplissez les valeurs manquantes avec des valeurs interpolées (2). Mais fais attention! Le remplacement d'un grand nombre de données par des observations remplies ou interpolées pourrait sérieusement interrompre votre jeu de données et conduire à de très mauvaises conclusions.

Voici quelques exemples d'utilisation de votre extrait ...

seaborn.distplot(data['alcconsumption'],hist=True,bins=100)
plt.xlabel('AlcoholConsumption')
plt.ylabel('Frequency(normalized 0->1)')

... sur un jeu de données synthétique:

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

def sample(rows, names):
    ''' Function to create data sample with random returns

    Parameters
    ==========
    rows : number of rows in the dataframe
    names: list of names to represent assets

    Example
    =======

    >>> sample(rows = 2, names = ['A', 'B'])

                  A       B
    2017-01-01  0.0027  0.0075
    2017-01-02 -0.0050 -0.0024
    '''
    listVars= names
    rng = pd.date_range('1/1/2017', periods=rows, freq='D')
    df_temp = pd.DataFrame(np.random.randint(-100,100,size=(rows, len(listVars))), columns=listVars) 
    df_temp = df_temp.set_index(rng)


    return df_temp

df = sample(rows = 15, names = ['A', 'B'])
df['A'][8:12] = np.nan
df

Production:

            A   B
2017-01-01 -63.0  10
2017-01-02  49.0  79
2017-01-03 -55.0  59
2017-01-04  89.0  34
2017-01-05 -13.0 -80
2017-01-06  36.0  90
2017-01-07 -41.0  86
2017-01-08  10.0 -81
2017-01-09   NaN -61
2017-01-10   NaN -80
2017-01-11   NaN -39
2017-01-12   NaN  24
2017-01-13 -73.0 -25
2017-01-14 -40.0  86
2017-01-15  97.0  60

(1) Utilisation du remplissage direct avec pandas.DataFrame.fillna (méthode = ffill)

ffill "remplira les valeurs vers l'avant", ce qui signifie qu'il remplacera les nan par la valeur de la ligne ci-dessus.

df = df['A'].fillna(axis=0, method='ffill')
sns.distplot(df, hist=True,bins=5)
plt.xlabel('AlcoholConsumption')
plt.ylabel('Frequency(normalized 0->1)')

enter image description here

(2) Utilisation de l'interpolation avec pandas.DataFrame.interpolate ()

Interpoler les valeurs selon différentes méthodes. L'interpolation temporelle fonctionne sur des données de résolution quotidienne et supérieure pour interpoler une longueur d'intervalle donnée.

df['A'] = df['A'].interpolate(method = 'time')
sns.distplot(df['A'], hist=True,bins=5)
plt.xlabel('AlcoholConsumption')
plt.ylabel('Frequency(normalized 0->1)')

enter image description here

Comme vous pouvez le voir, les différentes méthodes rendent deux résultats très différents. J'espère que cela vous sera utile. Sinon, faites-le moi savoir et j'y reviendrai.

3
vestland

Vous pouvez utiliser la ligne suivante pour sélectionner les valeurs non NaN pour un graphique de distribution utilisant seaborn:

seaborn.distplot(data['alcconsumption'].notnull(),hist=True,bins=100)
3
ZicoNuna

C'est un problème connu avec les histogrammes matplotlib/pylab!

Voir par exemple https://github.com/matplotlib/matplotlib/issues/648

où diverses solutions de contournement sont suggérées, deux favoris (par exemple de https://stackoverflow.com/a/19090183/1021819 ) étant:

import numpy as np
nbins=100
A=data['alcconsumption']
Anan=A[~np.isnan(A)] # Remove the NaNs

seaborn.distplot(Anan,hist=True,bins=nbins)

Sinon, spécifiez les bords du bac (dans ce cas en utilisant de toute façon Anan...):

Amin=min(Anan)
Amax=max(Anan)
seaborn.distplot(A,hist=True,bins=np.linspace(Amin,Amax,nbins))
2
jtlz2