Seaborn配对图和NaN值

时间:2015-07-18 16:58:30

标签: python pandas matplotlib seaborn

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

  

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

3 个答案:

答案 0 :(得分:3)

直接使用数据时,即

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

您正在绘制DataFrame中的所有列,然后确保所有列中的行数相同。

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

在这种情况下,它可以正常工作,但图表中会有一点微小差异,用于删除“NaN”值。

  

所以,如果你想用整个数据进行绘图,那么: -

  • 必须使用" fillna()",

  • 替换空值
  • 或包含' nan值'的整行。必须放弃

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

    pairplot for dropped values

答案 1 :(得分:2)

我会回答我自己的问题,即使它并没有完全解决问题,但至少它解决了我的问题。

尝试绘制直方图时出现问题。但是,看起来Tuple对于丢失数据更加健壮。因此,尽管数据框中间有kde,但这仍然有效:

NaN

答案 2 :(得分:0)

某种坏事-但当我今天破解这个答案时,我认为值得分享。我无法在网络上的其他地方找到此解决方案...如果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下降,返回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)

使用海洋绘图(例如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)