Apakah ada builtin numpy untuk melakukan sesuatu seperti berikut? Yaitu, ambil daftar d
dan kembalikan daftar filtered_d
dengan elemen luar yang dihapus berdasarkan beberapa asumsi distribusi titik-titik di d
.
import numpy as np
def reject_outliers(data):
m = 2
u = np.mean(data)
s = np.std(data)
filtered = [e for e in data if (u - 2 * s < e < u + 2 * s)]
return filtered
>>> d = [2,4,5,1,6,5,40]
>>> filtered_d = reject_outliers(d)
>>> print filtered_d
[2,4,5,1,6,5]
Saya mengatakan 'sesuatu seperti' karena fungsinya memungkinkan untuk berbagai distribusi (poisson, gaussian, dll.) Dan memvariasikan ambang pencilan dalam distribusi tersebut (seperti yang m
saya gunakan di sini).
Jawaban:
Metode ini hampir identik dengan milik Anda, hanya lebih banyak numpyst (juga bekerja pada array numpy saja):
sumber
m
cukup besar (misalnyam=6
), tetapi untuk nilai-nilai kecilm
ini menderita mean varians bukan penduga yang kuat.Sesuatu yang penting ketika menangani pencilan adalah bahwa seseorang harus mencoba menggunakan estimator sekuat mungkin. Rata-rata distribusi akan menjadi bias oleh pencilan tetapi misalnya median akan jauh lebih sedikit.
Membangun jawaban eumiro:
Di sini saya mengganti mean dengan median yang lebih kuat dan deviasi standar dengan jarak absolut median ke median. Saya kemudian menskalakan jarak dengan nilai mediannya (lagi) sehingga
m
berada pada skala relatif yang masuk akal.Perhatikan bahwa agar
data[s<m]
sintaks berfungsi,data
harus berupa array numpy.sumber
3.5 / .6745 ~= 5.189
(mereka mengalikans
dengan 0,6745 dan menentukan anm
dari 3,5 ... juga ambilabs(s)
). Adakah yang bisa menjelaskan pilihan m? Atau apakah itu sesuatu yang akan Anda identifikasi dari kumpulan data tertentu Anda?m
daripada pernyataan halus seperti "interaksi antara kemurnian dan efisiensi"?TypeError: only integer scalar arrays can be converted to a scalar index
Jawaban Benjamin Bannier menghasilkan pass-through ketika median jarak dari median adalah 0, jadi saya menemukan versi modifikasi ini sedikit lebih membantu untuk kasus-kasus seperti yang diberikan dalam contoh di bawah ini.
Contoh:
Memberikan:
sumber
Membangun dari Benjamin, menggunakan
pandas.Series
, dan mengganti MAD dengan IQR :Misalnya, jika Anda menyetel
iq_range=0.6
, persentil rentang interkuartil akan menjadi :,0.20 <--> 0.80
jadi lebih banyak pencilan akan disertakan.sumber
Alternatifnya adalah membuat estimasi yang kuat dari deviasi standar (dengan asumsi statistik Gaussian). Mencari kalkulator online, saya melihat bahwa persentil 90% sesuai dengan 1,2815σ dan 95% adalah 1,645σ ( http://vassarstats.net/tabs.html?#z )
Sebagai contoh sederhana:
Output yang saya dapatkan adalah:
Yang mendekati nilai yang diharapkan dari 2.
Jika kita ingin menghapus poin di atas / di bawah 5 standar deviasi (dengan 1000 poin, kami mengharapkan 1 nilai> 3 standar deviasi):
Pemberian yang mana:
Saya tidak tahu pendekatan mana yang lebih efisien / kuat
sumber
Saya ingin memberikan dua metode dalam jawaban ini, solusi berdasarkan "skor z" dan solusi berdasarkan "IQR".
Kode yang diberikan dalam jawaban ini berfungsi pada
numpy
larik redup tunggal dannumpy
larik ganda .Mari impor beberapa modul terlebih dahulu.
z metode berbasis skor
Metode ini akan menguji apakah angka tersebut berada di luar tiga deviasi standar. Berdasarkan aturan ini, jika nilainya outlier, metode akan mengembalikan true, jika tidak, mengembalikan false.
Metode berbasis IQR
Metode ini akan menguji apakah nilainya kurang dari
q1 - 1.5 * iqr
atau lebih besar dariq3 + 1.5 * iqr
yang serupa dengan metode plot SPSS.Terakhir, jika Anda ingin memfilter pencilan, gunakan
numpy
selektor.Semoga harimu menyenangkan.
sumber
Pertimbangkan bahwa semua metode di atas gagal ketika standar deviasi Anda menjadi sangat besar karena pencilan yang sangat besar.
( Simalar sebagai penghitungan rata-rata gagal dan seharusnya menghitung median. Padahal, rata-rata "lebih rentan terhadap kesalahan seperti stdDv". )
Anda dapat mencoba menerapkan algoritme Anda secara berulang atau memfilter menggunakan rentang interkuartil: (di sini "faktor" berkaitan dengan rentang * sigma, namun hanya jika data Anda mengikuti distribusi Gaussian)
sumber
Saya ingin melakukan sesuatu yang serupa, kecuali mengatur nomor ke NaN daripada menghapusnya dari data, karena jika Anda menghapusnya, Anda mengubah panjangnya yang dapat mengacaukan plotting (yaitu jika Anda hanya menghapus pencilan dari satu kolom dalam tabel , tetapi Anda membutuhkannya untuk tetap sama dengan kolom lainnya sehingga Anda dapat memplotkannya satu sama lain).
Untuk melakukannya saya menggunakan fungsi masking numpy :
sumber
jika ingin mendapatkan posisi indeks maka pencilan
idx_list
akan mengembalikannya.sumber
Untuk satu set gambar (setiap gambar memiliki 3 dimensi), di mana saya ingin menolak outlier untuk setiap piksel yang saya gunakan:
Maka dimungkinkan untuk menghitung mean:
(Saya menggunakannya untuk Pengurangan Latar Belakang)
sumber