Menghapus Data NaN di Numpy
Misalkan kita memiliki 10 data pengukuran dari tiga sensor. Pertama, kita mencari elemen NaN sebagai berikut.In [1]: import numpy as np In [2]: a = np.array([[1, 2, 4], [1, 2, 1], [np.nan, 1, 2], [1, 2, np.nan], [2, 1, 1]]) In [3]: np.isnan(a).any() Out[3]: True In [4]: np.where(np.isnan(a)) Out[4]: (array([2, 3]), array([0, 2]))
Dari output ipython tersebut kita mengetahui bahwa data NaN berada pada (2, 0) dan (3, 2). Ingat Python mengindeks dari 0. Untuk menghapus baris (row) yang berisi NaN, gunakan perintah berikut:
In [3]: b = a[~np.isnan(a).any(axis=1)]
Algoritma menghapus NaN pada satu baris di atas dapat dijelaskan sbb:
1. Mencari indeks data NaN dengan np.isnan.
2. Mencari data jika ada NaN dengan np.any.
3. Mencari data jika ada NaN pada kolom (axis=1, karena yang kita hapus barisnya).
4. Membalik hasil pencarian pada (1-3) dengan ~, dengan kata lain, cari data yang bukan NaN.
Untuk lebih jelasnya, perhatikan setiap output perintah berikut:
In [57]: np.isnan(a) Out[57]: array([[False, False, False], [False, False, False], [ True, False, False], [False, False, True], [False, False, False]]) In [58]: np.isnan(a).any() Out[58]: True In [59]: np.isnan(a).any(axis=1) Out[59]: array([False, False, True, True, False]) In [60]: ~np.isnan(a).any(axis=1) Out[60]: array([ True, True, False, False, True]) In [61]: a[~np.isnan(a).any(axis=1)] Out[61]: array([[1., 2., 4.], [1., 2., 1.], [2., 1., 1.]])Baris untuk memfilter data NaN disebut fancy indexing. Inilah salah satu hal yang paling membedakan Numpy dengan List python. Dengan teknik ini kita bisa memfilter suatu array dengan array lainnya. Contohnya data dengan index NaN ini. Permasalahan menghapus data yang berisi NaN selesai.
Mengganti Data Nan di Numpy
Bagaimana jika kita tidak ingin menghapus dana NaN, tapi mengubahnya..? Misal, dalam pengukuran suhu, suhu yang tidak terbaca sensor kita anggap sebagai suhu 25 derajat celcius.Berikut data dummy pengukuran tiga sensor suhu.
In [52]: a = np.random.uniform(23, 28, [10, 3]) In [53]: a Out[53]: array([[27.78837233, 23.24395001, 23.57374599], [24.19978931, 23.25094801, 24.49294423], [26.73693715, 23.16475293, 25.96576384], [26.70315233, 24.85865614, 25.3510446 ], [25.31885087, 27.42903322, 25.26193883], [25.68032566, 27.06242615, 27.0408585 ], [26.64473586, 27.56036335, 24.49159284], [24.90196938, 26.00082306, 25.70781393], [26.58828295, 25.36263426, 27.6251521 ], [24.63801191, 24.23193679, 26.99034562]])
Kita tambahkan 5 data NaN secara acak.
In [54]: a.ravel()[np.random.choice(a.size, 5, replace=False)] = np.nan In [55]: a Out[55]: array([[27.78837233, nan, nan], [24.19978931, 23.25094801, 24.49294423], [26.73693715, 23.16475293, 25.96576384], [26.70315233, 24.85865614, 25.3510446 ], [ nan, 27.42903322, 25.26193883], [25.68032566, 27.06242615, 27.0408585 ], [26.64473586, 27.56036335, nan], [24.90196938, 26.00082306, 25.70781393], [26.58828295, nan, 27.6251521 ], [24.63801191, 24.23193679, 26.99034562]])
Terlihat 5 data NaN pada baris 0, 4, 6, dan 8 (indeks mulai dari 0). Kita ganti data NaN tersebut dengan 25.0 derajat celcius. Perintah yang digunakan adalan np.nan_to_num(a, nan=25.0).
In [56]: np.nan_to_num(a, nan=25.0) Out[56]: array([[27.78837233, 25. , 25. ], [24.19978931, 23.25094801, 24.49294423], [26.73693715, 23.16475293, 25.96576384], [26.70315233, 24.85865614, 25.3510446 ], [25. , 27.42903322, 25.26193883], [25.68032566, 27.06242615, 27.0408585 ], [26.64473586, 27.56036335, 25. ], [24.90196938, 26.00082306, 25.70781393], [26.58828295, 25. , 27.6251521 ], [24.63801191, 24.23193679, 26.99034562]])
Cukup sederhana, jika argumen nan=25.0 tidak ditambahkan, maka data NaN akan diganti dengan angka "0" (default). Jika ingin mengganti dengan angka lain, misal 25.5, tinggal mengganti nan=25.5. Selesai permasalahan mengganti data NaN pada Numpy array.
Untuk Pandas (dataframe) silahkan baca di sini.