用seaborn绘图时如何处理缺失值?

Roh*_*ota 12 python data-analysis python-2.7 pandas seaborn

我使用lambda跟随函数用NaN替换了缺少的值:

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

,数据是我正在处理的数据帧.

之后使用seaborn,我尝试绘制其中一个属性,使用seaborn.distplot进行alcconsumption,如下所示:

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

它给了我以下错误:

AttributeError: max must be larger than min in range parameter.
Run Code Online (Sandbox Code Playgroud)

小智 5

您可以使用以下行使用seaborn为分布图选择非NaN值:

seaborn.distplot(data['alcconsumption'].notnull(),hist=True,bins=100)
Run Code Online (Sandbox Code Playgroud)


ves*_*and 3

在绘制数据之前,我肯定会处理缺失值。是否不使用dropna()完全取决于数据集的性质。是alcconsumption单个系列还是数据框的一部分?在后一种情况下,使用dropna()也会删除其他列中的相应行。缺失值是少还是多?它们是分散在您的系列中,还是倾向于成组出现?是否有理由相信您的数据集中存在趋势?

如果缺失值很少且分散,您可以轻松使用 dropna()。在其他情况下,我会选择用之前观察到的值(1)填充缺失值。或者甚至用插值来填充缺失值(2)。不过要小心!用填充或插值的观察值替换大量数据可能会严重中断您的数据集并导致非常错误的结论。

以下是一些使用您的代码片段的示例...

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

...在合成数据集上:

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
Run Code Online (Sandbox Code Playgroud)

输出:

            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
Run Code Online (Sandbox Code Playgroud)

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)')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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)')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

正如您所看到的,不同的方法会呈现两种截然不同的结果。我希望这对你有用。如果没有,请告诉我,我会再看一遍。