Ada dua solusi yang mungkin:
- Gunakan topeng boolean, lalu gunakan
df.loc[mask]
- Atur kolom tanggal sebagai DatetimeIndex, lalu gunakan
df[start_date : end_date]
Menggunakan topeng boolean :
Pastikan df['date']
adalah Seri dengan dtype datetime64[ns]
:
df['date'] = pd.to_datetime(df['date'])
Buat topeng boolean. start_date
dan end_date
dapat berupa string datetime.datetime
s,
np.datetime64
s, pd.Timestamp
s, atau bahkan datetime:
#greater than the start date and smaller than the end date
mask = (df['date'] > start_date) & (df['date'] <= end_date)
Pilih sub-DataFrame:
df.loc[mask]
atau ditugaskan kembali df
df = df.loc[mask]
Sebagai contoh,
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.random((200,3)))
df['date'] = pd.date_range('2000-1-1', periods=200, freq='D')
mask = (df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')
print(df.loc[mask])
hasil panen
0 1 2 date
153 0.208875 0.727656 0.037787 2000-06-02
154 0.750800 0.776498 0.237716 2000-06-03
155 0.812008 0.127338 0.397240 2000-06-04
156 0.639937 0.207359 0.533527 2000-06-05
157 0.416998 0.845658 0.872826 2000-06-06
158 0.440069 0.338690 0.847545 2000-06-07
159 0.202354 0.624833 0.740254 2000-06-08
160 0.465746 0.080888 0.155452 2000-06-09
161 0.858232 0.190321 0.432574 2000-06-10
Menggunakan DatetimeIndex :
Jika Anda akan melakukan banyak pilihan berdasarkan tanggal, mungkin lebih cepat untuk mengatur
date
kolom sebagai indeks terlebih dahulu. Kemudian Anda dapat memilih baris berdasarkan tanggal menggunakan
df.loc[start_date:end_date]
.
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.random((200,3)))
df['date'] = pd.date_range('2000-1-1', periods=200, freq='D')
df = df.set_index(['date'])
print(df.loc['2000-6-1':'2000-6-10'])
hasil panen
0 1 2
date
2000-06-01 0.040457 0.326594 0.492136 # <- includes start_date
2000-06-02 0.279323 0.877446 0.464523
2000-06-03 0.328068 0.837669 0.608559
2000-06-04 0.107959 0.678297 0.517435
2000-06-05 0.131555 0.418380 0.025725
2000-06-06 0.999961 0.619517 0.206108
2000-06-07 0.129270 0.024533 0.154769
2000-06-08 0.441010 0.741781 0.470402
2000-06-09 0.682101 0.375660 0.009916
2000-06-10 0.754488 0.352293 0.339337
Sementara pengindeksan daftar Python, misalnya seq[start:end]
termasuk start
tetapi tidak end
, sebaliknya, Pandas df.loc[start_date : end_date]
menyertakan kedua titik akhir dalam hasil jika mereka berada dalam indeks. Namun, keduanya start_date
tidak end_date
harus berada dalam indeks.
Perhatikan juga bahwa pd.read_csv
memiliki parse_dates
parameter yang dapat Anda gunakan untuk mem-parsing date
kolom sebagai datetime64
s. Jadi, jika Anda menggunakan parse_dates
, Anda tidak perlu menggunakannya df['date'] = pd.to_datetime(df['date'])
.
df = df.set_index(['date'])
langkah tersebut, saya telah menemukan indeks juga perlu disortir (viadf.sort_index(inplace=True, ascending=True)
), karena jika tidak, Anda bisa mendapatkan hasil DataFrame kurang dari penuh atau bahkan kosongdf.loc['2000-6-1':'2000-6-10']
. Dan jika Anda menggunakanascending=False
, itu tidak akan berhasil sama sekali, bahkan jika Anda membalikkannya dengandf.loc['2000-6-10':'2000-6-1']
Saya merasa pilihan terbaik adalah menggunakan cek langsung daripada menggunakan fungsi loc:
Ini bekerja untuk saya.
Masalah utama dengan fungsi loc dengan slice adalah batas harus ada pada nilai aktual, jika tidak ini akan menghasilkan KeyError.
sumber
loc
sangat bagus. Dan menurut saya seperti yang dikatakan unutbu, baik start_date maupun end_date tidak harus ada dalam indeks .Anda juga dapat menggunakan
between
:sumber
between_time
: pandas.pydata.org/pandas-docs/version/0.20.3/generated/…Anda dapat menggunakan
isin
metode padadate
kolom seperti itudf[df["date"].isin(pd.date_range(start_date, end_date))]
Catatan: Ini hanya berfungsi dengan tanggal (saat pertanyaan diajukan) dan bukan cap waktu.
Contoh:
pemberian yang mana
sumber
Menjaga solusinya sederhana dan pythonic, saya sarankan Anda untuk mencoba ini.
Jika Anda akan sering melakukan ini, solusi terbaik adalah dengan terlebih dahulu mengatur kolom tanggal sebagai indeks yang akan mengkonversi kolom di DateTimeIndex dan menggunakan kondisi berikut untuk mengiris berbagai tanggal.
sumber
Dengan pengujian
pandas
versi0.22.0
saya sekarang Anda dapat menjawab pertanyaan ini dengan lebih mudah dengan kode yang lebih mudah dibaca hanya dengan menggunakanbetween
.Katakanlah Anda ingin mengambil tanggal antara 27 November 2018 dan 15 Januari 2019:
Perhatikan argumen inklusif. sangat membantu ketika Anda ingin menjadi eksplisit tentang jangkauan Anda. perhatikan ketika disetel ke True, kami juga mengembalikan 27 November 2018:
Metode ini juga lebih cepat daripada
isin
metode yang disebutkan sebelumnya :Namun, itu tidak lebih cepat dari jawaban yang saat ini diterima, disediakan oleh unutbu, hanya jika topeng sudah dibuat . tetapi jika topeng itu dinamis dan perlu dipindahkan ulang berulang kali, metode saya mungkin lebih efisien:
sumber
Pilihan lain, bagaimana mencapainya, adalah dengan menggunakan
pandas.DataFrame.query()
metode. Izinkan saya menunjukkan kepada Anda sebuah contoh pada kerangka data berikut yang disebutdf
.Sebagai argumen, gunakan kondisi untuk memfilter seperti ini:
Jika Anda tidak ingin menyertakan batasan, cukup ubah kondisi seperti berikut:
sumber
Saya lebih suka tidak mengubah
df
.Pilihan adalah untuk mengambil
index
daristart
danend
tanggal:yang mengakibatkan:
sumber