Seaborne Bierblatt 和 Nun Walus

Seaborn pairplot and NaN values

我试图理解为什么这会失败,即使文档说:

dropna : boolean, optional Drop missing values from the data before plotting.

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

直接使用数据时,即

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 value'.

的图表中会有微小的差异

So, If you want to plot with the whole Data then :-

  • 必须使用 "fillna()"、

  • 替换空值
  • 或必须删除包含 'nan values' 的整行

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

我要 post 回答我自己的问题,尽管它不能完全解决一般问题,但至少它解决了 我的 问题。

尝试绘制直方图时出现问题。但是,看起来 kde 对缺失数据的鲁棒性要强得多。因此,尽管数据帧中间有 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')

有点死机了-但是当我今天破解了这个问题的答案时,我认为它可能值得分享。我无法在网络上的其他地方找到此解决方案...如果 Seaborn ignoreNa 关键字对您的数据不起作用并且您不想删除所有具有任何 NaN 的行。这应该适合你。

所有这些都在 Seaborn 0.9 中 pandas 0.23.4,假设数据框 (df) 有 j 行(样本)和 n 列(属性)。

解决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,我们可以最大限度地减少每个样本的数据丢失(排)。这是因为一行中的一个 NaN 不会导致所有子图丢失整行。而只是该特定列对的子图将排除给定的行。

以下函数执行成对的NaN drop,returns seaborn然后用matplotlibs散点图在轴上绘制的两个系列:

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)

同样可以用 seaborn 绘图来完成(例如,只有 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)