Pandas: Jendela bergulir dengan ukuran langkah

Dibuat pada 9 Feb 2017  ·  38Komentar  ·  Sumber: pandas-dev/pandas

Sekedar saran - perluas rolling untuk mendukung jendela bergulir dengan ukuran langkah, seperti R's rollapply(by=X) .

Contoh Kode

Pandas - solusi tidak efisien (terapkan fungsi ke setiap jendela, lalu iris untuk mendapatkan hasil setiap detik)

import pandas
ts = pandas.Series(range(0, 40, 2))
ts.rolling(5).apply(max).dropna()[::2]

Saran:

ts = pandas.Series(range(0, 40, 2))
ts.rolling(window=5, step=2).apply(max).dropna()

Terinspirasi oleh R (lihat dokumen rollapply ):

require(zoo)
TS <- zoo(seq(0, 40, 2))
rollapply(TS, 5, FUN=max, by=2)

8 12 16 20 24 28 32 36 40

Enhancement Needs Discussion Numeric Window

Komentar yang paling membantu

"ini bisa dilakukan, tetapi saya ingin melihat usecase di mana ini penting."

Apa pun proyek yang saya kerjakan menggunakan panda, saya hampir selalu melewatkan fitur ini, ini berguna setiap kali Anda perlu menghitung apply hanya sesekali tetapi masih membutuhkan resolusi yang baik di dalam setiap jendela.

Semua 38 komentar

Jika Anda menggunakan fungsi 'standar', ini di-vektorkan, dan sangat cepat ( ts.rolling(5).max().dropna()[::2] ).

IIUC penghematan di sini akan datang dari hanya menerapkan fungsi sebagian kecil dari waktu (misalnya setiap nilai ke-n). Tetapi apakah ada kasus di mana hal itu membuat perbedaan praktis?

ini bisa dilakukan, tetapi saya ingin melihat usecase di mana ini penting. Ini juga akan merusak API 'mengembalikan ukuran yang sama dengan input'. Meskipun saya tidak berpikir ini sebenarnya sulit untuk diterapkan (meskipun akan melibatkan sejumlah perubahan dalam implementasi). Kami menggunakan jendela marginal (IOW, hitung jendela dan saat Anda maju, turunkan poin yang tersisa dan tambahkan poin yang Anda peroleh). Jadi masih harus menghitung semuanya, tetapi Anda tidak akan mengeluarkannya.

Terima kasih atas balasan Anda!

IIUC penghematan di sini akan datang dari hanya menerapkan fungsi sebagian kecil dari waktu (misalnya setiap nilai ke-n). Tetapi apakah ada kasus di mana hal itu membuat perbedaan praktis?

Kasus penggunaan saya menjalankan fungsi agregasi (bukan hanya maks) pada beberapa kerangka data deret waktu besar - 400 kolom, jam data pada 5-25Hz. Saya juga pernah melakukan hal serupa (rekayasa fitur pada data sensor) di masa lalu dengan data hingga 20kHz. Menjalankan jendela 30 detik dengan langkah 5 detik menghemat sebagian besar pemrosesan - misalnya pada 25Hz dengan langkah 5 detik, ini adalah 1/125 dari pekerjaan, yang membuat perbedaan antara berjalan dalam 1 menit atau 2 jam.

Saya jelas dapat kembali ke numpy, tetapi alangkah baiknya jika ada API tingkat yang lebih tinggi untuk melakukan ini. Saya hanya berpikir itu layak untuk saran jika orang lain akan menganggapnya berguna juga - saya tidak berharap Anda membuat fitur hanya untuk saya!

Anda dapat mencoba resamplimg ke interval frekuensi yang lebih tinggi terlebih dahulu kemudian bergulir

sesuatu seperti

df = df.resample('30s')
df.rolling(..).max() (atau fungsi apa pun)

Hai @jreback , terima kasih atas sarannya.

Ini akan berfungsi jika saya baru saja menjalankan max pada data saya (sampel ulang memerlukan fungsi pengurangan, jika tidak, defaultnya adalah mean , kan?):

df.resample('1s').max().rolling(30).max()

Namun saya ingin menjalankan fungsi reduksi saya pada data 30 detik, lalu maju 1 detik, dan menjalankannya pada data 30 detik berikutnya, dll. Metode di atas menerapkan fungsi pada 1 detik data, dan kemudian yang lain fungsi pada 30 hasil fungsi pertama.

Berikut ini contoh cepat - menjalankan penghitungan puncak ke puncak tidak berfungsi berjalan dua kali (jelas):

# 10 minutes of data at 5Hz
n = 5 * 60 * 10
rng = pandas.date_range('1/1/2017', periods=n, freq='200ms')
np.random.seed(0)
d = np.cumsum(np.random.randn(n), axis=0)
s = pandas.Series(d, index=rng)

# Peak to peak
def p2p(d):
    return d.max() - d.min()

def p2p_arr(d):
    return d.max(axis=1) - d.min(axis=1)

def rolling_with_step(s, window, step, func):
    # See https://ga7g08.github.io/2015/01/30/Applying-python-functions-in-moving-windows/
    vert_idx_list = np.arange(0, s.size - window, step)
    hori_idx_list = np.arange(window)
    A, B = np.meshgrid(hori_idx_list, vert_idx_list)
    idx_array = A + B
    x_array = s.values[idx_array]
    idx = s.index[vert_idx_list + int(window/2.)]
    d = func(x_array)
    return pandas.Series(d, index=idx)

# Plot data
ax = s.plot(figsize=(12, 8), legend=True, label='Data')

# Plot resample then rolling (obviously does not work)
s.resample('1s').apply(p2p).rolling(window=30, center=True).apply(p2p).plot(ax=ax, label='1s p2p, roll 30 p2p', legend=True)

# Plot rolling window with step
rolling_with_step(s, window=30 * 5, step=5, func=p2p_arr).plot(ax=ax, label='Roll 30, step 1s', legend=True)

rolling window

@alexlouden dari deskripsi asli Anda, saya pikir sesuatu seperti

df.resample('5s').max().rolling('30s').mean() (atau pengurangan apa pun) lebih sesuai dengan yang Anda inginkan

TKI, ambil apa pun yang ada di tempat sampah 5 detik, lalu kurangi menjadi satu titik, lalu gulingkan tempat sampah itu. Gagasan umum ini adalah bahwa Anda memiliki banyak data yang dapat diringkas dalam skala waktu yang singkat, tetapi Anda sebenarnya ingin menggulungnya pada tingkat yang lebih tinggi.

Hai @jreback , saya sebenarnya ingin menjalankan fungsi lebih dari 30 detik data, setiap 5 detik. Lihat fungsi rolling_with_step dalam contoh saya sebelumnya. Langkah tambahan max/mean tidak berfungsi untuk kasus penggunaan saya.

@jreback , ada kebutuhan nyata untuk fungsi langkah yang belum dibawa dalam diskusi ini. Saya mendukung semua yang telah dijelaskan oleh

Misalkan kita melakukan analisis deret waktu dengan data masukan yang diambil sampelnya kira-kira 3 hingga 10 milidetik. Kami tertarik dengan fitur domain frekuensi. Langkah pertama dalam membangunnya adalah mencari tahu frekuensi Nyquist. Misalkan dengan pengetahuan domain kita tahu bahwa 10 Hz (setiap 100 ms sekali). Artinya, kita membutuhkan data yang memiliki frekuensi minimal 20 Hz (setiap 50 ms sekali), jika fitur tersebut harus menangkap sinyal input dengan baik. Kami tidak dapat mengambil sampel ulang ke frekuensi yang lebih rendah dari itu. Akhirnya di sini adalah perhitungan yang kami lakukan:

df.resample('50ms').mean().rolling(window=32).aggregate(power_spectrum_coeff)

Di sini kami memilih ukuran jendela kelipatan 8, dan memilih 32 membuat ukuran jendela menjadi 1,6 detik. Fungsi agregat mengembalikan koefisien domain frekuensi satu sisi dan tanpa komponen rata-rata pertama (fungsi fft adalah simetris dan dengan nilai rata-rata pada elemen ke-0). Berikut ini adalah contoh fungsi agregat:

def power_spectrum_coeff():
    def power_spectrum_coeff_(x):
        return np.fft.fft(x)[1 : int(len(x) / 2 + 1)]

    power_spectrum_coeff_.__name__ = 'power_spectrum_coeff'
    return power_spectrum_coeff_

Sekarang, kami ingin mengulangi ini di jendela geser, katakanlah, setiap 0,4 detik atau setiap 0,8 detik. Tidak ada gunanya membuang-buang perhitungan dan menghitung FFT setiap 50 ms sebagai gantinya dan kemudian mengiris nanti. Selanjutnya, resampling ke 400 ms bukanlah pilihan, karena 400 ms hanya 2,5 Hz, yang jauh lebih rendah daripada frekuensi Nyquist dan hal itu akan mengakibatkan semua informasi hilang dari fitur.

Ini adalah fitur domain frekuensi, yang memiliki aplikasi dalam banyak eksperimen ilmiah terkait deret waktu. Namun, fungsi agregat domain waktu yang lebih sederhana seperti deviasi standar tidak dapat didukung secara efektif dengan pengambilan sampel ulang.

Meskipun saya tidak berpikir ini sebenarnya sulit untuk diterapkan (meskipun akan melibatkan sejumlah perubahan dalam implementasi). Kami menggunakan jendela marginal (IOW, hitung jendela dan saat Anda maju, turunkan poin yang tersisa dan tambahkan poin yang Anda peroleh). Jadi masih harus menghitung semuanya, tetapi Anda tidak akan menampilkannya.

Memiliki parameter 'langkah' dan mampu mengurangi perhitungan aktual dengan menggunakannya harus menjadi tujuan masa depan Pandas. Jika parameter step hanya mengembalikan poin yang lebih sedikit, maka itu tidak layak dilakukan, karena bagaimanapun kita dapat mengiris output. Mungkin mengingat pekerjaan yang terlibat dalam melakukan ini, kami mungkin hanya merekomendasikan semua proyek dengan kebutuhan ini untuk menggunakan Numpy.

@Murmuria Anda dipersilakan untuk mengirimkan permintaan tarik untuk melakukan ini. Ini sebenarnya tidak terlalu sulit.

Sementara saya mendukung permintaan untuk parameter step di rolling() , saya ingin menunjukkan bahwa adalah mungkin untuk mendapatkan hasil yang diinginkan dengan parameter base di resample() , jika ukuran langkah adalah pecahan bilangan bulat dari ukuran jendela . Menggunakan contoh @alexlouden :

pandas.concat([
    s.resample('30s', label='left', loffset=pandas.Timedelta(15, unit='s'), base=i).agg(p2p) 
    for i in range(30)
]).sort_index().plot(ax=ax, label='Solution with resample()', legend=True, style='k:')

Kami mendapatkan hasil yang sama (perhatikan bahwa garis memanjang 30 detik di kedua sisi):
rolling_with_step_using_resample

Ini masih agak boros, tergantung pada jenis agregasi. Untuk kasus tertentu dari perhitungan peak-to-peak seperti pada contoh @alexlouden , p2p_arr() hampir 200x lebih cepat karena ia mengatur ulang deret ke matriks 2-D dan kemudian menggunakan satu panggilan ke max() dan min() .

Parameter langkah dalam pengguliran juga memungkinkan penggunaan fitur ini tanpa indeks waktu-tanggal. Apakah ada yang sudah mengerjakannya?

@alexlouden di atas mengatakan ini:

Saya jelas dapat kembali ke numpy, tetapi alangkah baiknya jika ada API tingkat yang lebih tinggi untuk melakukan ini.

Bisakah @alexlouden atau siapa pun yang tahu berbagi wawasan tentang cara melakukan ini dengan numpy? Dari penelitian saya selama ini, sepertinya tidak sepele untuk melakukan ini baik di numpy. Faktanya, ada masalah terbuka tentang itu di sini https://github.com/numpy/numpy/issues/7753

Terima kasih

Hai @tsando - apakah fungsi rolling_with_step saya gunakan di atas tidak berfungsi untuk Anda?

@alexlouden terima kasih, baru saja memeriksa fungsi itu dan sepertinya masih bergantung pada panda (mengambil seri sebagai input dan juga menggunakan indeks seri). Saya bertanya-tanya apakah ada pendekatan yang murni numpy dalam hal ini. Di utas yang saya sebutkan https://github.com/numpy/numpy/issues/7753 mereka mengusulkan fungsi yang menggunakan langkah numpy, tetapi sulit untuk dipahami dan diterjemahkan ke input jendela dan langkah.

@tsando Inilah PDF dari posting blog yang saya tautkan di atas - sepertinya penulis telah mengubah nama pengguna Github-nya dan belum memasang situsnya lagi. (Saya baru saja menjalankannya secara lokal untuk mengonversinya ke PDF).

Fungsi saya di atas adalah saya hanya mengonversi contoh terakhirnya untuk bekerja dengan Pandas - jika Anda ingin menggunakan numpy secara langsung, Anda dapat melakukan sesuatu seperti ini: https://Gist.github.com/alexlouden/e42f1d96982f7f005e62ebb737dcd987

Semoga ini membantu!

@alexlouden terima kasih! Saya baru saja mencobanya pada array bentuk (13, 1313) tetapi memberi saya kesalahan ini:

image

"ini bisa dilakukan, tetapi saya ingin melihat usecase di mana ini penting."

Apa pun proyek yang saya kerjakan menggunakan panda, saya hampir selalu melewatkan fitur ini, ini berguna setiap kali Anda perlu menghitung apply hanya sesekali tetapi masih membutuhkan resolusi yang baik di dalam setiap jendela.

Saya setuju dan mendukung fitur ini juga

Membutuhkannya hampir setiap saat ketika berhadapan dengan deret waktu, fitur tersebut dapat memberikan kontrol yang jauh lebih baik untuk menghasilkan fitur deret waktu baik untuk visualisasi maupun analisis. Sangat mendukung ide ini!

setuju dan dukung fitur ini juga

Ini akan sangat membantu untuk mengurangi waktu komputasi dengan tetap menjaga resolusi jendela yang baik.

Saya memberikan kode solusi, yang dapat disesuaikan lebih lanjut sesuai dengan target khusus Anda.

def average_smoothing(signal, kernel_size, stride):
    sample = []
    start = 0
    end = kernel_size
    while end <= len(signal):
        start = start + stride
        end = end + stride
        sample.append(np.mean(signal[start:end]))
    return np.array(sample)

Saya setuju dan mendukung fitur ini. Saya melihat dalam stop motion sekarang.

Menghitung dan kemudian downsampling bukanlah pilihan ketika Anda memiliki banyak data.

Ini akan sangat membantu dalam apa yang saya lakukan juga. Saya memiliki banyak data di mana saya memerlukan berbagai statistik jendela yang tidak tumpang tindih untuk memahami kondisi lokal. "Perbaikan" saya saat ini adalah membuat generator yang memotong bingkai data dan statistik hasil. Akan sangat membantu untuk memiliki fitur ini.

Fitur ini memang harus dimiliki saat melibatkan time series!

Setuju, pasti perlu ditambahkan fitur ini. Mencoba menjalankan korelasi jendela antara harga saham dan harus membuat fungsi saya sendiri untuk itu

Tidak percaya fitur dasar seperti itu belum ada!
Kapan masalah ini akan diselesaikan?
Terima kasih

Untuk berkontribusi pada 'diskusi lebih lanjut':
Kasus penggunaan saya adalah menghitung satu nilai min/maks/median per jam untuk satu bulan data dengan resolusi 1 detik. Ini data penggunaan energi dan ada puncak selama 1-2 detik yang akan saya hilangkan dengan resampling. Selain itu, resampling ke misalnya 5 detik/1 menit tidak akan mengubah fakta bahwa saya masih harus menghitung 4k/1k windows per hari yang perlu dibuang, daripada hanya bisa menghitung 24 windows yang dibutuhkan per hari .

Dimungkinkan untuk mengatasi ini dengan menggunakan groupby aso tetapi itu tampaknya tidak intuitif atau secepat implementasi bergulir (2 detik untuk jendela 2,5 juta jam dengan penyortiran). Ini sangat cepat dan berguna, tetapi kami benar-benar membutuhkan argumen langkah untuk sepenuhnya memanfaatkan kekuatannya.

Saya melihat masalahnya. Ini relatif sepele, namun cara kode diimplementasikan, dari tampilan sepintas saya pikir itu akan membutuhkan seseorang untuk bekerja keras melalui pengeditan manual semua rutinitas bergulir. Tak satu pun dari mereka menghormati batas jendela yang diberikan oleh kelas pengindeks. Jika mereka melakukannya, baik permintaan ini maupun #11704 akan sangat mudah dipecahkan. Bagaimanapun, saya pikir ini dapat dikelola oleh siapa saja yang ingin meluangkan waktu untuk merapikan segalanya. Saya memulai PR setengah matang (diharapkan ditolak, hanya untuk MVP) untuk menunjukkan bagaimana saya akan mengatasi masalah tersebut.

Berlari:

import numpy as np
import pandas as pd

data = pd.Series(
    np.arange(100),
    index=pd.date_range('2020/05/12 12:00:00', '2020/05/12 12:00:10', periods=100))

print('1s rolling window every 2s')
print(data.rolling('1s', step='2s').apply(np.mean))

data.sort_index(ascending=False, inplace=True)

print('1s rolling window every 500ms (and reversed)')
print(data.rolling('1s', step='500ms').apply(np.mean))

hasil

1s rolling window every 2s
2020-05-12 12:00:00.000000000     4.5
2020-05-12 12:00:02.020202020    24.5
2020-05-12 12:00:04.040404040    44.5
2020-05-12 12:00:06.060606060    64.5
2020-05-12 12:00:08.080808080    84.5
dtype: float64
1s rolling window every 500ms (and reversed)
2020-05-12 12:00:10.000000000    94.5
2020-05-12 12:00:09.494949494    89.5
2020-05-12 12:00:08.989898989    84.5
2020-05-12 12:00:08.484848484    79.5
2020-05-12 12:00:07.979797979    74.5
2020-05-12 12:00:07.474747474    69.5
2020-05-12 12:00:06.969696969    64.5
2020-05-12 12:00:06.464646464    59.5
2020-05-12 12:00:05.959595959    54.5
2020-05-12 12:00:05.454545454    49.5
2020-05-12 12:00:04.949494949    44.5
2020-05-12 12:00:04.444444444    39.5
2020-05-12 12:00:03.939393939    34.5
2020-05-12 12:00:03.434343434    29.5
2020-05-12 12:00:02.929292929    24.5
2020-05-12 12:00:02.424242424    19.5
2020-05-12 12:00:01.919191919    14.5
2020-05-12 12:00:01.414141414     9.5
2020-05-12 12:00:00.909090909     4.5
dtype: float64

Untuk detail implementasi, lihat PR (atau di sini: https://github.com/anthonytw/pandas/tree/rolling-window-step)

Sementara saya ingin menghabiskan lebih banyak waktu untuk menyelesaikannya, sayangnya saya tidak punya waktu untuk menangani pekerjaan kasar dari pengerjaan ulang semua fungsi bergulir. Rekomendasi saya untuk siapa saja yang ingin mengatasi ini adalah dengan menegakkan batas jendela yang dihasilkan oleh kelas pengindeks dan menyatukan fungsi rolling_*_fixed/variabel. Dengan batas awal dan akhir, saya tidak melihat alasan mengapa mereka harus berbeda, kecuali jika Anda memiliki fungsi yang melakukan sesuatu yang istimewa dengan data sampel yang tidak seragam (dalam hal ini fungsi tertentu akan lebih mampu menangani nuansa, jadi mungkin menetapkan bendera atau sesuatu).

Apakah ini juga berfungsi untuk jendela khusus menggunakan pendekatan get_window_bounds() ?

Hai, saya juga kedua sarannya. Ini akan menjadi fitur yang sangat berguna.

Jika Anda menggunakan fungsi 'standar', ini di-vektorkan, dan sangat cepat ( ts.rolling(5).max().dropna()[::2] ).

IIUC penghematan di sini akan datang dari hanya menerapkan fungsi sebagian kecil dari waktu (misalnya setiap nilai ke-n). Tetapi apakah ada kasus di mana hal itu membuat perbedaan praktis?

Saya punya contoh seperti itu di sini: https://stackoverflow.com/questions/63729190/pandas-resample-daily-data-to-annual-data-with-overlap-and-offset

Setiap N akan menjadi setiap 365. Ukuran jendela bervariasi selama masa program dan langkah tidak dijamin menjadi pecahan bilangan bulat dari ukuran jendela.

Saya pada dasarnya membutuhkan ukuran jendela yang ditetapkan yang melangkah dengan "# hari dalam setahun yang dilihatnya" yang tidak mungkin dilakukan dengan setiap solusi yang saya temukan untuk masalah ini sejauh ini.

Saya juga memiliki kebutuhan serupa dengan konteks berikut (diadaptasi dari kebutuhan nyata dan profesional):

  • Saya memiliki kerangka data kronologis dengan kolom stempel waktu dan kolom nilai, yang mewakili peristiwa tidak teratur. Seperti stempel waktu ketika seekor anjing lewat di bawah jendela saya dan berapa detik yang dibutuhkannya untuk lewat. Saya dapat memiliki 6 acara untuk hari tertentu dan kemudian tidak ada acara sama sekali selama 2 hari ke depan
  • Saya ingin menghitung metrik (misalkan waktu rata-rata yang dihabiskan oleh anjing di depan jendela saya) dengan jendela bergulir 365 hari, yang akan bergulir setiap 30 hari

Sejauh yang saya mengerti, dataframe.rolling() API memungkinkan saya untuk menentukan durasi 365 hari, tetapi tidak perlu melewatkan nilai 30 hari (yang merupakan jumlah baris yang tidak konstan) untuk menghitung rata-rata berikutnya di atas yang lain pemilihan nilai 365 hari.

Jelas, kerangka data yang dihasilkan yang saya harapkan akan memiliki (jauh) jumlah baris yang lebih sedikit daripada kerangka data 'acara anjing' awal.

Hanya untuk mendapatkan kejelasan lebih lanjut tentang permintaan ini dengan contoh sederhana.

Jika kita memiliki Seri ini:

In [1]: s = pd.Series(range(5))

In [2]: s
Out[2]:
0    0
1    1
2    2
3    3
4    4
dtype: int64

dan kami memiliki ukuran jendela 2 dan ukuran langkah 1 . Jendela pertama pada indeks 0 akan dievaluasi, melangkahi jendela pada indeks 1 , mengevaluasi jendela pada indeks 2 , dll?

In [3]: s.rolling(2, step=1, min_periods=0).max()

Out[3]:
0    0.0
1    NaN # step over this observation
2    2.0
3    NaN # step over this observation
4    4.0
dtype: float64

Demikian juga jika kita memiliki Seri berbasis waktu ini

In [1]: s = pd.Series(range(5), index=pd.DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-06', '2020-01-09']))

In [2]: s
Out[2]:
2020-01-01    0
2020-01-02    1
2020-01-03    2
2020-01-06    3
2020-01-09    4
dtype: int64

dan kami memiliki ukuran jendela '3D' dan ukuran langkah '3D' . Apakah ini akan menjadi hasil yang benar?

In [3]: s.rolling('3D', step='3D', min_periods=0).max()

Out[3]:
2020-01-01    0.0       # evaluate this window
2020-01-02    NaN    # step over this observation (2020-01-01 + 3 days > 2020-01-02)
2020-01-03    NaN    # step over this observation (2020-01-01 + 3 days > 2020-01-03)
2020-01-06    3.0      # evaluate this window ("snap back" to this observation)
2020-01-09    4.0      # evaluate this window (2020-01-06 + 3 days = 2020-01-09)
dtype: float64

@mroeschke wrt untuk contoh pertama ([3]), hasilnya tidak seperti yang saya harapkan. Saya berasumsi ini adalah jendela tambahan (misalnya, pada indeks=0 itu akan menjadi elemen maksimal pada -1 dan 0, jadi hanya maks([0]), maka itu harus melangkah maju indeks "1", ke indeks=0 +langkah=1, dan perhitungan berikutnya adalah max([0,1]), lalu max([1,2]), dll. Apa yang terlihat seperti yang Anda maksud adalah ukuran langkah dua, jadi Anda akan melakukannya pindah dari indeks=0 ke indeks=0+2=2 (melewati indeks 1), dan terus seperti itu. Dalam hal ini hampir benar, tetapi seharusnya tidak ada NaN. Meskipun mungkin "hanya" dua kali lipat ukuran dalam hal ini kasus, dalam kasus lain itu penting. Misalnya, saya memiliki sekitar satu jam data EKG 500Hz untuk pasien, itu 1,8 juta sampel. Jika saya ingin rata-rata bergerak 5 menit setiap dua menit, itu akan menjadi array 1,8 juta elemen dengan 30 perhitungan yang valid dan sedikit kurang dari 1,8 juta NaN. :-)

Untuk pengindeksan, ukuran langkah = 1 adalah perilaku saat ini, yaitu, hitung fitur yang diinginkan menggunakan data di jendela, geser jendela satu per satu, lalu ulangi. Dalam contoh ini, saya ingin menghitung fitur yang diinginkan menggunakan data di jendela, lalu menggeser 60.000 indeks, lalu ulangi.

Komentar serupa untuk saat ini. Dalam hal ini, mungkin ada beberapa ketidaksepakatan tentang cara yang benar untuk menerapkan jenis jendela ini, tetapi menurut saya cara "terbaik"(TM) adalah mulai dari waktu t0, temukan semua elemen dalam rentang (t0-jendela , t0], hitung fiturnya, lalu pindahkan menurut ukuran langkah. Buang semua jendela yang memiliki jumlah elemen kurang dari jumlah minimum (dapat dikonfigurasi, default ke 1). Contoh itu untuk jendela tambahan, tetapi Anda dapat memodifikasi agar sesuai dengan konfigurasi jendela apa pun. Ini memiliki kelemahan membuang waktu di celah besar, tetapi celah dapat ditangani dengan cerdas dan bahkan jika Anda menghitung dengan cara yang naif (karena Anda malas seperti saya) Saya belum pernah melihat masalah ini dalam praktik , karena kesenjangan biasanya tidak cukup besar untuk masalah dalam data nyata.YMMV.

Mungkin itu lebih jelas? Lihatlah contoh saya + kode di atas, yang mungkin menjelaskannya dengan lebih baik.

Terima kasih atas klarifikasinya @anthonytw. Memang, sepertinya saya perlu menafsirkan step sebagai "langkah ke titik".

Adapun NaN, saya memahami sentimen untuk menjatuhkan NaN dalam hasil keluaran secara otomatis, tetapi seperti yang disebutkan dalam https://github.com/pandas-dev/pandas/issues/15354#issuecomment -278676420 oleh @jreback , ada pertimbangan konsistensi API agar output memiliki panjang yang sama dengan input. Mungkin ada pengguna yang ingin menyimpan NaN juga (mungkin?), dan dropna akan tetap tersedia setelah operasi rolling(..., step=...).func() .

@mroeschke Saya pikir pengecualian harus dibuat. Selama Anda memasukkan catatan eksplisit dalam dokumentasi, dan perilakunya tidak default, tidak ada yang akan terpengaruh dengan tidak mengembalikan vektor yang penuh sampah. Menjaga NaNs mengalahkan setengah tujuan. Salah satu tujuannya adalah untuk membatasi berapa kali kita melakukan komputasi yang mahal. Tujuan lainnya adalah untuk meminimalkan fitur yang disetel ke sesuatu yang dapat dikelola. Contoh yang saya berikan kepada Anda adalah contoh nyata, dan tidak sebanyak data yang harus diproses dalam aplikasi pemantauan pasien. Apakah benar-benar perlu mengalokasikan 60000x ruang yang diperlukan, lalu mencari melalui array untuk menghapus NaN? Untuk setiap fitur yang ingin kita hitung?

Perhatikan bahwa satu perhitungan mungkin menghasilkan array nilai. Apa yang ingin saya lakukan dengan gelombang EKG? Nah, hitung spektrum daya, tentu saja! Jadi saya perlu mengalokasikan ruang yang cukup untuk 1 vektor PSD penuh (150.000 elemen) 1,8 juta kali (data 2TB) kemudian menyaring untuk mendapatkan potongan yang saya pedulikan (34MB). Untuk semua seri. Untuk semua pasien. Saya kira saya perlu membeli lebih banyak RAM!

Perlu juga disebutkan bahwa NaN, untuk beberapa fitur, mungkin merupakan keluaran yang berarti. Dalam hal ini, saya tidak lagi dapat membedakan antara NaN yang bermakna dan NaN sampah yang mengisi data.

Meskipun saya memahami keinginan untuk mempertahankan API, ini bukan fitur yang akan merusak kode yang ada (karena ini adalah fitur baru yang belum ada sebelumnya), dan mengingat fungsionalitasnya, tidak ada alasan bagi siapa pun untuk mengharapkannya menghasilkan keluaran dengan ukuran yang sama. Dan bahkan jika mereka melakukannya, catatan dalam dokumentasi untuk ukuran langkah sudah cukup. Kerugiannya jauh lebih besar daripada manfaat memiliki API "konsisten" (untuk fitur yang sebelumnya tidak ada, ingatlah). Tidak melanjutkan dengan cara ini akan melumpuhkan fitur, bahkan hampir tidak layak diterapkan dalam kasus itu (dalam pengalaman saya, biaya ruang hampir selalu merupakan faktor yang lebih besar).

Apakah halaman ini membantu?
0 / 5 - 0 peringkat