web-dev-qa-db-ja.com

seabornでプロットするときに欠損値をどうするか?

次の関数を使用して、欠損値をNaNに置き換えました。

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

ここで、dataは私が取り組んでいるデータフレームです。

その後seabornを使用して、次のようにseaborn.distplotを使用してその属性の1つである消費をプロットしようとしました:

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

それは私に次のエラーを与えています:

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

私は間違いなく欠損値を扱います前にデータをプロットします。 dropna()を使用しないかどうかは、データセットの性質に完全に依存します。 alcconsumptionは単一のシリーズですか、それともデータフレームの一部ですか?後者の場合、dropna()を使用すると、他の列の対応する行も削除されます。欠損値は少ないですか、多いですか?それらはあなたのシリーズで広がっていますか、それともグループで発生する傾向がありますか?データセットに傾向があると信じる理由があるのでしょうか?

欠損値が少なく、散在している場合は、dropna()を簡単に使用できます。他の場合では、以前に観測された値(1)で欠損値を埋めることを選択します。または、欠落している値を補間値で埋めます(2)。しかし、注意してください!多数のデータを塗りつぶした、または内挿した観測で置き換えると、データセットに深刻な影響を与え、非常に間違った結論につながる可能性があります。

ここにあなたのスニペットを使用するいくつかの例があります...

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

...合成データセット:

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

出力:

            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) pandas.DataFrame.fillna(method = ffill) でフォワードフィルを使用する

ffillは「前方に値を入力」します。つまり、nanを上の行の値に置き換えます。

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) pandas.DataFrame.interpolate() で補間を使用する

さまざまな方法に従って値を補間します。時間補間は、毎日およびより高い解像度のデータに作用して、指定された間隔の長さを補間します。

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

ご覧のように、異なる方法では2つの非常に異なる結果がレンダリングされます。これがお役に立てば幸いです。そうでない場合はお知らせください。もう一度確認します。

3
vestland

次の行を使用して、seabornを使用した分布プロットの非NaN値を選択できます。

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

これは、matplotlib/pylabヒストグラムの既知の問題です。

たとえば、 https://github.com/matplotlib/matplotlib/issues/648

さまざまな回避策が提案されている場合、2つのお気に入り(たとえば https://stackoverflow.com/a/19090183/1021819 から)は次のとおりです。

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

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

または、ビンのエッジを指定します(この場合はとにかくAnan...を使用します)。

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