1. 程式人生 > 其它 >numpy中處理含nan資料的統計函式及其效率

numpy中處理含nan資料的統計函式及其效率

技術標籤:技術綜合pythonnumpy

numpy 庫中的一些統計函式,它們在遇到含 nan 的資料時都無法正常使用,需要換成可用的同名函式(即在函式名前加“nan”)。

1、相關函式

1.1、最大值 max()、nanmax() / 最小值 min() nanmin()

沿指定軸返回一個數組的最小 / 大值。
numpy.max(a, axis=None, out=None, keepdims=)
引數:
a - array_like ,陣列或者可以轉化成陣列的物件
axis - 無 None(預設)、整型 int、元組 tuple;沿軸線方向的操作方式

1.2、百分位數 percentile 、nanpercentile

計算陣列中沿指定方向上的第q 數值百分位(點),可以計算多維陣列的任意百分比分位數
numpy.percentile(a, q, axis=None, out=None, overwrite_input=False, interpolation=‘linear’, keepdims=False)
引數:
a - array_like ,陣列或者可以轉化成陣列的物件
q - [ 0., 100. ] 百分位
overwrite_input - bool 型引數,為 True 並且 a 的型別是ndarray,則 a 將被部分後者全部排序
axis - 無 None(預設)、整型 int、元組 tuple;沿軸線方向的操作方式

1.3、中位數 median、nanmedian

計算陣列 a 在沿 axis 軸方向上的中位數
numpy.median(a, axis=None, out=None, overwrite_input=False, keepdims=False)
引數:
a - array_like ,陣列或者可以轉化成陣列的物件
overwrite_input - bool 型引數,為 True 並且 a 的型別是ndarray,則 a 將被部分後者全部排序
axis - 無 None(預設)、整型 int、元組 tuple;沿軸線方向的操作方式

1.4、2.4 標準差std、nanstd

沿指定軸計算陣列的標準偏差。

numpy.std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=)
引數:
a - array_like ,陣列或者可以轉化成陣列的物件
ddof - 自由度,計算時的分母為 N(資料數量) - ddof,預設 ddof = 0
axis - 無 None(預設)、整型 int、元組 tuple;沿軸線方向的操作方式

1.5、方差var、nanvar

沿指定軸計算陣列的方差 var 【 = mean(abs(x - x.mean()) ** 2)】。
numpy.var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=)
引數:
a - array_like ,陣列或者可以轉化成陣列的物件
ddof - 自由度,計算時的分母為 N(資料數量) - ddof,預設 ddof = 0
axis - 無 None(預設)、整型 int、元組 tuple;沿軸線方向的操作方式

2、注意事項

2.1、陣列中有nan的影響

在含有 nan 數值的陣列上採用不帶 “nan”字首的統計函式處理,結果都是返回 nan ,需要換成帶 “nan”字首的同名統計函式處理。

2.2、相同功能的不同函式效率比較

以取包含 nan 的數組裡的最大值為例,有以下方法

import numpy as np
import pandas as pd
from time import time

arr1 = np.arange(100000)
arr2 = np.repeat(np.ndarray(np.nan), 10000)
arr = np.concatenate((arr1, arr2))
ser = pd.Series(arr)

# 從陣列中找最大值
t1 = time()
m1 = np.nanmax(arr)
print(f'1、np.nanmax(arr),用時 {time()-t1}')

t1 = time()
m2 = np.nanmax(ser.values)
print(f'2、np.nanmax(ser.values),用時 {time()-t1}')

t1 = time()
m2 = np.nanmax(ser)
print(f'3、np.nanmax(ser),用時 {time()-t1}')

t1 = time()
m2 = ser.max()
print(f'4、ser.max(),用時 {time()-t1}')
[Out]:
1、np.nanmax(arr),用時 0.0009999275207519531
2、np.nanmax(ser.values),用時 0.0
3、np.nanmax(ser),用時 0.0
4、ser.max(),用時 0.00500035285949707

其中,第 2、3 個的時間差幾乎為0,看看耗時到底多少?

t1 = time()
m2 = np.nanmax(ser.values)
print(f't1 = {t1}')
print(f't2 = {time()}')
[Out]:
t1 = 1609675066.2239056
t2 = 1609675066.2259057

可見,耗時最多的是 直接對 Series 取 .max(),耗時最少的是用 np.max() 求陣列的最大值。
其他函式也類似。

參考資料:
1、numpy 統計函式
2、numpy的np.nanmax和np.array([1,2,3,np.nan]).max()的區別(坑)