복붙노트

[PYTHON] 열등 배열 : 열의 평균으로 나노 값 바꾸기

PYTHON

열등 배열 : 열의 평균으로 나노 값 바꾸기

나는 실제 숫자로 채워진 질적 인 배열을 가지고있다. 그러나 그 안에 몇개의 값이있다.

nans를 열의 평균값으로 대체하려면 어떻게해야합니까?

해결법

  1. ==============================

    1.필요한 루프가 없습니다.

    필요한 루프가 없습니다.

    print(a)
    [[ 0.93230948         nan  0.47773439  0.76998063]
     [ 0.94460779  0.87882456  0.79615838  0.56282885]
     [ 0.94272934  0.48615268  0.06196785         nan]
     [ 0.64940216  0.74414127         nan         nan]]
    
    #Obtain mean of columns as you need, nanmean is just convenient.
    col_mean = np.nanmean(a, axis=0)
    print(col_mean)
    [ 0.86726219  0.7030395   0.44528687  0.66640474]
    
    #Find indicies that you need to replace
    inds = np.where(np.isnan(a))
    
    #Place column means in the indices. Align the arrays using take
    a[inds] = np.take(col_mean, inds[1])
    
    print(a)
    [[ 0.93230948  0.7030395   0.47773439  0.76998063]
     [ 0.94460779  0.87882456  0.79615838  0.56282885]
     [ 0.94272934  0.48615268  0.06196785  0.66640474]
     [ 0.64940216  0.74414127  0.44528687  0.66640474]]
    
  2. ==============================

    2.numpy 만 사용하는 표준 방법은 마스크 된 배열 모듈을 사용하는 것입니다.

    numpy 만 사용하는 표준 방법은 마스크 된 배열 모듈을 사용하는 것입니다.

    Scipy는 외부 라이브러리에 의존하는 꽤 무거운 패키지이므로 numpy 전용 메서드를 사용하는 것이 좋습니다. 이것은 @ DonaldHobson의 대답에서 차용합니다.

    편집 : np.nanmean은 이제 numpy 함수입니다. 그러나, 그것은 모든 열을 처리하지 않습니다 ...

    배열 a가 있다고 가정 해보십시오.

    >>> a
    array([[  0.,  nan,  10.,  nan],
           [  1.,   6.,  nan,  nan],
           [  2.,   7.,  12.,  nan],
           [  3.,   8.,  nan,  nan],
           [ nan,   9.,  14.,  nan]])
    
    >>> import numpy.ma as ma
    >>> np.where(np.isnan(a), ma.array(a, mask=np.isnan(a)).mean(axis=0), a)    
    array([[  0. ,   7.5,  10. ,   0. ],
           [  1. ,   6. ,  12. ,   0. ],
           [  2. ,   7. ,  12. ,   0. ],
           [  3. ,   8. ,  12. ,   0. ],
           [  1.5,   9. ,  14. ,   0. ]])
    

    마스킹 된 배열의 평균은 a와 같은 모양 일 필요는 없습니다. 왜냐하면 우리는 행에 대한 암시 적 브로드 캐스팅을 이용하기 때문입니다.

    또한 all-nan 컬럼이 어떻게 잘 처리되는지 주목하십시오. 당신은 0 원소의 평균을 취하고 있기 때문에 평균은 0입니다. nanmean을 사용하는 방법은 all-nan 열을 처리하지 않습니다.

    >>> col_mean = np.nanmean(a, axis=0)
    /home/praveen/.virtualenvs/numpy3-mkl/lib/python3.4/site-packages/numpy/lib/nanfunctions.py:675: RuntimeWarning: Mean of empty slice
      warnings.warn("Mean of empty slice", RuntimeWarning)
    >>> inds = np.where(np.isnan(a))
    >>> a[inds] = np.take(col_mean, inds[1])
    >>> a
    array([[  0. ,   7.5,  10. ,   nan],
           [  1. ,   6. ,  12. ,   nan],
           [  2. ,   7. ,  12. ,   nan],
           [  3. ,   8. ,  12. ,   nan],
           [  1.5,   9. ,  14. ,   nan]])
    

    설명

    마스크 된 배열로 변환하면

    >>> ma.array(a, mask=np.isnan(a))
    masked_array(data =
     [[0.0 --  10.0 --]
      [1.0 6.0 --   --]
      [2.0 7.0 12.0 --]
      [3.0 8.0 --   --]
      [--  9.0 14.0 --]],
                 mask =
     [[False  True False  True]
     [False False  True  True]
     [False False False  True]
     [False False  True  True]
     [ True False False  True]],
           fill_value = 1e+20)
    

    열에 대한 평균을 취하면 정답을 얻을 수 있으며 마스크되지 않은 값에 대해서만 정규화됩니다.

    >>> ma.array(a, mask=np.isnan(a)).mean(axis=0)
    masked_array(data = [1.5 7.5 12.0 --],
                 mask = [False False False  True],
           fill_value = 1e+20)
    

    더구나, 마스크가 all-nan 인 컬럼을 멋지게 처리하는 방법에 유의하십시오.

    마지막으로, np.where는 교체 작업을 수행합니다.

    행 현명한 평균

    nan 값을 열 단위 평균 대신 행 단위 평균으로 바꾸려면 브로드 캐스팅을 효율적으로 적용하려면 약간의 변경이 필요합니다.

    >>> a
    array([[  0.,   1.,   2.,   3.,  nan],
           [ nan,   6.,   7.,   8.,   9.],
           [ 10.,  nan,  12.,  nan,  14.],
           [ nan,  nan,  nan,  nan,  nan]])
    
    >>> np.where(np.isnan(a), ma.array(a, mask=np.isnan(a)).mean(axis=1), a)
    ValueError: operands could not be broadcast together with shapes (4,5) (4,) (4,5)
    
    >>> np.where(np.isnan(a), ma.array(a, mask=np.isnan(a)).mean(axis=1)[:, np.newaxis], a)
    array([[  0. ,   1. ,   2. ,   3. ,   1.5],
           [  7.5,   6. ,   7. ,   8. ,   9. ],
           [ 10. ,  12. ,  12. ,  12. ,  14. ],
           [  0. ,   0. ,   0. ,   0. ,   0. ]])
    
  3. ==============================

    3.partial이 원본 데이터이고 replace가 평균 값을 포함하는 동일한 모양의 배열이면이 코드는 partial이있는 경우 값을 사용합니다.

    partial이 원본 데이터이고 replace가 평균 값을 포함하는 동일한 모양의 배열이면이 코드는 partial이있는 경우 값을 사용합니다.

    Complete= np.where(np.isnan(partial),replace,partial)
    
  4. ==============================

    4.대안 : NaN을 컬럼 보간으로 대체.

    대안 : NaN을 컬럼 보간으로 대체.

    def interpolate_nans(X):
        """Overwrite NaNs with column value interpolations."""
        for j in range(X.shape[1]):
            mask_j = np.isnan(X[:,j])
            X[mask_j,j] = np.interp(np.flatnonzero(mask_j), np.flatnonzero(~mask_j), X[~mask_j,j])
        return X
    

    사용 예 :

    X_incomplete = np.array([[10,     20,     30    ],
                             [np.nan, 30,     np.nan],
                             [np.nan, np.nan, 50    ],
                             [40,     50,     np.nan    ]])
    
    X_complete = interpolate_nans(X_incomplete)
    
    print X_complete
    [[10,     20,     30    ],
     [20,     30,     40    ],
     [30,     40,     50    ],
     [40,     50,     50    ]]
    

    특히 열이 속성이고 행이 시간 순서가 지정된 샘플 인 경우 시계열 데이터에이 코드를 사용합니다.

  5. ==============================

    5.이것은 매우 깨끗하지는 않지만 iterating 이외의 방법으로는 생각할 수 없다.

    이것은 매우 깨끗하지는 않지만 iterating 이외의 방법으로는 생각할 수 없다.

    #example
    a = np.arange(16, dtype = float).reshape(4,4)
    a[2,2] = np.nan
    a[3,3] = np.nan
    
    indices = np.where(np.isnan(a)) #returns an array of rows and column indices
    for row, col in zip(*indices):
        a[row,col] = np.mean(a[~np.isnan(a[:,col]), col])
    
  6. ==============================

    6.Donald 's Answer를 연장하기 위해 나는 최소한의 예를 제시한다. a가 ndarray이고 그 0 값을 컬럼의 평균으로 대체하려고한다고 가정합시다.

    Donald 's Answer를 연장하기 위해 나는 최소한의 예를 제시한다. a가 ndarray이고 그 0 값을 컬럼의 평균으로 대체하려고한다고 가정합시다.

    In [231]: a
    Out[231]: 
    array([[0, 3, 6],
           [2, 0, 0]])
    
    
    In [232]: col_mean = np.nanmean(a, axis=0)
    Out[232]: array([ 1. ,  1.5,  3. ])
    
    In [228]: np.where(np.equal(a, 0), col_mean, a)
    Out[228]: 
    array([[ 1. ,  3. ,  6. ],
           [ 2. ,  1.5,  3. ]])
    
  7. ==============================

    7.루프에 간단한 함수 사용 :

    루프에 간단한 함수 사용 :

    a=[[0.93230948, np.nan, 0.47773439, 0.76998063],
      [0.94460779, 0.87882456, 0.79615838, 0.56282885],
      [0.94272934, 0.48615268, 0.06196785, np.nan],
      [0.64940216, 0.74414127, np.nan, np.nan],
      [0.64940216, 0.74414127, np.nan, np.nan]]
    
    print("------- original array -----")
    for aa in a:
        print(aa)
    
    # GET COLUMN MEANS: 
    ta = np.array(a).T.tolist()                         # transpose the array; 
    col_means = list(map(lambda x: np.nanmean(x), ta))  # get means; 
    print("column means:", col_means)
    
    # REPLACE NAN ENTRIES WITH COLUMN MEANS: 
    nrows = len(a); ncols = len(a[0]) # get number of rows & columns; 
    for r in range(nrows):
        for c in range(ncols):
            if np.isnan(a[r][c]):
                a[r][c] = col_means[c]
    
    print("------- means added -----")
    for aa in a:
        print(aa)
    

    산출:

    ------- original array -----
    [0.93230948, nan, 0.47773439, 0.76998063]
    [0.94460779, 0.87882456, 0.79615838, 0.56282885]
    [0.94272934, 0.48615268, 0.06196785, nan]
    [0.64940216, 0.74414127, nan, nan]
    [0.64940216, 0.74414127, nan, nan]
    
    column means: [0.82369018599999999, 0.71331494500000003, 0.44528687333333333, 0.66640474000000005]
    
    ------- means added -----
    [0.93230948, 0.71331494500000003, 0.47773439, 0.76998063]
    [0.94460779, 0.87882456, 0.79615838, 0.56282885]
    [0.94272934, 0.48615268, 0.06196785, 0.66640474000000005]
    [0.64940216, 0.74414127, 0.44528687333333333, 0.66640474000000005]
    [0.64940216, 0.74414127, 0.44528687333333333, 0.66640474000000005]
    

    for 루프는 목록 이해력으로 작성할 수도 있습니다.

    new_a = [[col_means[c] if np.isnan(a[r][c]) else a[r][c] 
                for c in range(ncols) ]
            for r in range(nrows) ]
    
  8. ==============================

    8.다음과 같은 내장 함수를 사용해보십시오.

    다음과 같은 내장 함수를 사용해보십시오.

    x = np.array([np.inf, -np.inf, np.nan, -128, 128])
    np.nan_to_num(x)
    array([  1.79769313e+308,  -1.79769313e+308,   0.00000000e+000,
    -1.28000000e+002,   1.28000000e+002])
    
  9. from https://stackoverflow.com/questions/18689235/numpy-array-replace-nan-values-with-average-of-columns by cc-by-sa and MIT license