当前位置 博文首页 > 如何将numpy二维数组中的np.nan值替换为指定的值

    如何将numpy二维数组中的np.nan值替换为指定的值

    作者:PythonStyle 时间:2021-06-06 17:50

    基础知识:

    (1)np.nan表示该值不是一个数,比如数据中收入、年龄的缺失值;np.inf表示无穷大

    (2)np.nan == np.nan 的结果为False

    (3)nan与任何数的操作结果均为nan,例如sum((np.nan,4)) 的结果为nan

    (4)一个ndarray数组t1,可以用np.isnan(t1) 定位到nan值的位置,再用t1[np.isnan(t1)] = 指定值 将nan替换为指定值

    (5)np.nan_to_num(t1),可以将t1中的nan替换为0

    (6)t1[ t1 == t1]可以剔除所有nan只保留非nan值

    现在生成一个3*4的数组,设定第1行,第2、3列位置两个元素为np.nan

    import numpy as np
    t1 = np.arange(12).reshape(3,4).astype('float')
    t1[1,2:] = np.nan
    print(t1)

    [[ 0. 1. 2. 3.]

    [ 4. 5. nan nan]

    [ 8. 9. 10. 11.]]

    1. 问题1:

    如何将t1中的nan替换为0

    #方法1:
    for i in range(t1.shape[1]):
        col = t1[:,i]
        col[np.isnan(col)] = 0
    #方法2:调用np.nan_to_num方法
    t1 = np.nan_to_num(t1)
    #方法3:或用np.isnan(t1)做索引,然后替换,建议用该方法
    t1[np.isnan(t1)] = 0

    方法3不但可以替换为0,替换为其它值也可,建议使用。

    2. 问题2:

    如何将t1中的nan替换为某些计算之后的值,例如将其替换为该列所有非 nan元素的均值

    将原始数据中缺失的值替换为0有时未必是合适的。例如原始数据中某些人的年龄没有填,如果替换为0,将来在计算年龄平均值或做数据分析时就存在不合理的后果。此时,将年龄缺失的的人的年龄设为均值更为合理。

    (1)方法1

    #方法1:
    for i in range(t1.shape[1]):
        col = t1[:,i]
        #当前列中如果存在nan,由于np.nan不等于np.nan,所以如果某列中存在nan,则col!=col将会有元素为True,np.count_nonzero方法将会累计值为True的元素数量,可以通过这种方法来判断该列是否存在nan
        nan_num = np.count_nonzero(col != col)
        if nan_num:
            not_nan_col = col[col == col] #用布尔矩阵col == col做索引来筛选矩阵,布尔矩阵中False位置的元素将被剔除。
            col[np.isnan(col)] = not_nan_col.mean()
    print(t1)

    运行结果:

    [[ 0. 1. 2. 3.]

    [ 4. 5. 6. 7.]

    [ 8. 9. 10. 11.]]

    (2)方法2

    #方法2:np.nanmean方法可以计算非nan值的均值,此外还有np.nanmax, np.nanmin方法。所以上述程序可以改写如下:
    mean = np.nanmean(t1,axis=0)
    print('各列的均值为:%s' %mean)
    for i in range(t1.shape[1]):
        col = t1[:,i]
        col[np.isnan(col)] = mean[i]
    print(t1)

    运行结果同上

    (3)方法3

    使用功能强大的pandas库

    #也可以用pandas来处理,更为简单便捷
    import pandas as pd
    df = pd.DataFrame(t1)
    t1 = df.fillna(df.mean()).values  #values代替as_matrix(),可以将DataFrame转换为ndarray
    print(t1)

    运行结果同上。

    补充:python 快速替换Numpy 中的Nan(空值)和inf (无限值)

    在做数据处理的时候由于要保证数据的个数不变,需要把数据中的空值和无穷值替换为指定的值(此处为255),考虑到数据量比较大(50000000条数据),效率也是一个考虑因素。

    下面主要给出了替换数据的核心代码

    # +--+--+--+--+--+--+--+--+--+--+
    print('Predict New Data......')
    start = datetime.datetime.now()
    
    dataPre = input_Data   # 此处输入需要处理的原始数据
    
    # 0: 00:23.012951  标记了这个方法的时间(以50000000条数据为例)
    dataPre0 = np.array(dataPre)
    dataPre0[np.isnan(dataPre0)] = 255
    dataPre0[np.isinf(dataPre0)] = 255
    
    # 0:02:03.038840
    dataPre1 = (dataPre)
    dataPre1 = dataPre1.replace([np.inf, -np.inf], np.nan)
    dataPre1 = dataPre1.fillna(value = 255)
    
    # 0:02:03.140287
    dataPre2 = (dataPre)
    dataPre2 = (dataPre2.replace([np.inf, -np.inf], np.nan)).fillna(value = 255)    # shi yong te ding shuju tian chong
    
    # 0:00:30.346661
    dataPre3 = np.array(dataPre)
    dataPre3[(dataPre3 == float('inf')) | (dataPre3 == float('-inf')) | (dataPre3 == float('nan'))] = 255
    
    # 0:00:19.702519
    dataPre4 = np.array(dataPre)
    dataPre4[np.isinf(dataPre4)] = np.nan  # 将数组里面的无穷值转为空值
    dataPre4[np.isnan(dataPre4)] = 255  # # 将nan值替换为255
    
    # 0:01:10.404677
    dataPre5 = np.array(dataPre)
    dataPre5 = np.where(np.isnan(dataPre5), 255, dataPre5)
    dataPre5 = np.where(np.isinf(dataPre5), 255, dataPre5)
    

    可以看出几种方法的效率差别还是比较大的,尤其是使用了replace或者np.where函数的方法,比较慢。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持站长博客。

    js
    下一篇:没有了