web-dev-qa-db-ja.com

SeabornペアプロットとNaN値

ドキュメントに次のように書かれていても、なぜこれが失敗するのかを理解しようとしています。

dropna:ブール値、オプションプロットする前に、データから欠落している値を削除します。

from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
sns.__version__
# '0.7.dev'
# generate an example DataFrame
a = pd.DataFrame(data={
    'a': np.random.normal(size=(100,)),
    'b': np.random.lognormal(size=(100,)),
    'c': np.random.exponential(size=(100,))})
sns.pairplot(a) # this works as expected
# snip
b = a.copy()
b.iloc[5,2] = np.nan # replace one value in col 'c' by a NaN
sns.pairplot(b) # this fails with error 
                # "AttributeError: max must be larger than min in range parameter."
                # in histogram(a, bins, range, normed, weights, density)"
> sns.pairplot(b, dropna=True) # same error as above
6
Diziet Asahi

一般的に問題を正確に解決するわけではありませんが、少なくともmy問題は解決しますが、私は自分の質問に対する回答を投稿します。

ヒストグラムを描画しようとすると、問題が発生します。ただし、kdesは欠測データに対してはるかに堅牢であるように見えます。したがって、これは、データフレームの中央にNaNがあるにもかかわらず、機能します。

from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
sns.__version__
# '0.7.dev'
# generate an example DataFrame
a = pd.DataFrame(data={
    'a': np.random.normal(size=(100,)),
    'b': np.random.lognormal(size=(100,)),
    'c': np.random.exponential(size=(100,))})
a.iloc[5,2] = np.nan # replace one value in col 'c' by a NaN
sns.pairplot(a, diag_kind='kde')
3
Diziet Asahi

データを直接使用している場合、つまり

sns.pairplot(b) #Same as sns.pairplot(b, x_vars=['a','b','c'] , y_vars=['a','b','c'],dropna=True)

dataFrameのすべての列に対してプロットしている場合は、no:of行がすべての列で同じであることを確認してください。

sns.pairplot(b, x_vars=['a','c'] , y_vars=['a','b','c'],dropna=True)

この場合は正常に機能しますが、「NaN値」を削除するためのグラフにわずかな違いがあります。

したがって、データ全体でプロットしたい場合は:-

  • 「fillna()」を使用してnull値を置き換える必要があります。

  • または、「nan値」を含む行全体を削除する必要があります

    b = b.drop(b.index[5])
    sns.pairplot(b)
    

    pairplot for dropped values

3
Suresh2692

ネクロのようなものですが、今日私がこれに対する答えを割ったとき、私はそれを共有する価値があるかもしれないと思いました。この解決策はウェブ上の他の場所では見つかりませんでした... Seaborn ignoreNaキーワードがデータに対して機能せず、NaNを含むすべての行を削除したくない場合。これはあなたのために働くはずです。

これらはすべてSeaborn0.9にあり、pandas 0.23.4であり、n列(属性)を持つj行(サンプル)のデータフレーム(df)を想定しています。

Seabornが渡されたNaN配列に対処できないという問題の解決策。特に、有用な他のデータが含まれているために行を保持したい場合は、プロットのためにPairGridに渡される前にペアワイズ列をインターセプトする関数を使用することに基づいています。 。

関数をグリッドセクターに渡して、サブプロットごとに操作を実行できます。この簡単な例は、列ペア(サブプロット)のRMSEを計算し、各プロットに注釈を付けることです。

def rmse(x,y, **kwargs):
    rmse = math.sqrt(skm.mean_squared_error(x, y))

    label = 'RMSE = ' + str(round(rmse, 2))  
    ax = plt.gca()
    ax.annotate(label, xy = (0.1, 0.95), size = 20, xycoords = ax.transAxes)

grid = grid.map_upper(rmse)

したがって、Seabornがデータプロット引数として使用できる関数を作成することで、grid.map_がメインデータフレームを反復処理するときに列ペアベースでNaNをドロップするため、サンプル(行)あたりのデータ損失を最小限に抑えることができます。これは、行に1つのNaNがあると、すべてのサブプロットで行全体が失われるわけではないためです。ただし、その特定の列ペアのサブプロットだけで、指定された行が除外されます。

次の関数は、ペアワイズNaNドロップを実行し、seabornがmatplotlibs散布図を使用して軸にプロットする2つの系列を返します。

df = [YOUR DF HERE]

def col_nan_scatter(x,y, **kwargs):
    df = pd.DataFrame({'x':x[:],'y':y[:]})
    df = df.dropna()
    x = df['x']
    y = df['y']
    plt.gca()
    plt.scatter(x,y)  

cols = df.columns
grid = sns.PairGrid(data= df, vars = cols, height = 4)
grid = grid.map_upper(col_nan_scatter)

同じことが海のプロットでも行うことができます(たとえば、x値のみを使用)。

def col_nan_kde_histo(x, **kwargs):
    df = pd.DataFrame({'x':x[:]})
    df = df.dropna()
    x = df['x']
    plt.gca()
    sns.kdeplot(x)

cols = df.columns
grid = sns.PairGrid(data= df, vars = cols, height = 4)
grid = grid.map_upper(col_nan_scatter)
grid = grid.map_upper(col_nan_kde_histo)
1
Tom Dowling