kzen.dev
  • Întrebări
  • Tag-uri
  • Utilizatori
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
 darkpool
darkpool
Question

Selectați DataFrame rânduri între două date

Eu voi crea un DataFrame dintr-un fișier csv, după cum urmează:

stock = pd.read_csv('data_in/' + filename + '.csv', skipinitialspace=True)

DataFrame are o data de coloană. Există o modalitate de a crea un nou DataFrame (sau doar suprascrie unul existent), care conține doar rânduri cu valorile de dată care se încadrează într-un interval de timp specificat sau între două date specificate valori?

163 2015-03-31T13:38:06+00:00 7
Ezra Citron
Ezra Citron
Întrebarea editată 17 august 2018 в 4:25
Programare
python
pandas
Solution / Answer
 unutbu
unutbu
31 martie 2015 в 1:49
2015-03-31T13:49:49+00:00
Mai mult
Sursă
Editează
#27170336

Există două soluții posibile:

  • Folosiți un boolean masca, apoi utilizați df.loc[masca]
  • Setați data coloană ca o DatetimeIndex, apoi utilizați df[start_date : end_date]

Folosind un boolean masca:

Asigura df['data'] este o Serie cu dtype datetime64[ns]:

df['date'] = pd.to_datetime(df['date'])  

Face un boolean masca. start_date " și " end_date poate fi `datetime.datetime e, np.datetime64 e, pd.Timestamp, sau chiar datetime siruri de caractere:

#greater than the start date and smaller than the end date
mask = (df['date'] > start_date) & (df['date'] <= end_date)

Selectați sub-DataFrame:

df.loc[mask]

sau re-atribui "df"

df = df.loc[mask]

De exemplu, `` python import numpy ca np import panda ca pd

df = pd.DataFrame(np.aleatoare.aleatoare((200,3))) df['data'] = pd.date_range('2000-1-1', perioadele=200, freq='D') masca = (df['data'] > '2000-6-1') & (df['data'] <= '2000-6-10') print(df.loc[masca]) `` randamentele

            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

Folosind un DatetimeIndex:

Dacă aveți de gând să faceți o mulțime de selecții de data, aceasta poate fi mai rapid pentru a seta "data" coloană ca și indexul în primul rând. Apoi, puteți selecta rânduri de data folosind df.loc[start_date:end_date].

`` python import numpy ca np import panda ca pd

df = pd.DataFrame(np.aleatoare.aleatoare((200,3))) df['data'] = pd.date_range('2000-1-1', perioadele=200, freq='D') df = df.set_index(['data']) print(df.loc['2000-6-1':'2000-6-10']) ``

randamentele

                   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

În timp ce Python lista de indexare, de exemplu, urm[start:end]include "start", dar nu "sfârșitul", în contrast, Pandadf.loc[start_date : end_date]include *ambele* end-puncte în rezultat, dacă acestea sunt în index. Nicistart_date", nici " end_date` trebuie să fie în index cu toate acestea.


De asemenea, rețineți că pd.read_csv are o parse_dates parametru care le-ar putea folosi pentru a analiza coloana "data" ca datetime64 lui. Astfel, dacă utilizațiparse_dates, tu nu ar trebui să foloseascădf['data'] = pd.to_datetime(df['data'])`.

Jinhua Wang
Jinhua Wang
Răspuns editat 29 iunie 2019 в 12:19
337
0
Christin Jose
Christin Jose
13 iulie 2016 в 1:00
2016-07-13T01:00:33+00:00
Mai mult
Sursă
Editează
#27170337

Mă simt cea mai bună opțiune va fi de a folosi direct controale, mai degrabă decât folosind loc funcția:

df = df[(df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')]

Acesta funcționează pentru mine.

Problema majoră cu funcție de loc cu o felie este ca limitele ar trebui să fie prezente în valori reale, dacă nu acest lucru va duce la KeyError.

49
0
 pomber
pomber
5 martie 2018 в 9:28
2018-03-05T21:28:06+00:00
Mai mult
Sursă
Editează
#27170341

Puteți folosi, de asemenea, între`:

df[df.some_date.between(start_date, end_date)]
23
0
Jonny Brooks
Jonny Brooks
23 ianuarie 2017 в 8:47
2017-01-23T08:47:36+00:00
Mai mult
Sursă
Editează
#27170338

Puteți utiliza isin metoda pe coloana "data" ca asa df[df["data"].isin(pd.date_range(start_date, end_date))]

Notă: Aceasta funcționează numai cu datele (precum întrebarea cere) și nu marcajele de timp.

Exemplu:

import numpy as np   
import pandas as pd

# Make a DataFrame with dates and random numbers
df = pd.DataFrame(np.random.random((30, 3)))
df['date'] = pd.date_range('2017-1-1', periods=30, freq='D')

# Select the rows between two dates
in_range_df = df[df["date"].isin(pd.date_range("2017-01-15", "2017-01-20"))]

print(in_range_df)  # print result

care dă

           0         1         2       date
14  0.960974  0.144271  0.839593 2017-01-15
15  0.814376  0.723757  0.047840 2017-01-16
16  0.911854  0.123130  0.120995 2017-01-17
17  0.505804  0.416935  0.928514 2017-01-18
18  0.204869  0.708258  0.170792 2017-01-19
19  0.014389  0.214510  0.045201 2017-01-20
Jonny Brooks
Jonny Brooks
Răspuns editat 3 septembrie 2018 в 10:25
18
0
Abhinav Anand
Abhinav Anand
21 septembrie 2017 в 12:05
2017-09-21T12:05:25+00:00
Mai mult
Sursă
Editează
#27170339

Păstrarea soluție simplă și pythonic, aș sugera să încercați acest lucru.

În cazul în care aveți de gând pentru a face acest lucru în mod frecvent cea mai bună soluție ar fi să-și primul set la data de coloană ca și indexul care va converti coloană în DateTimeIndex și de a folosi următoarele stare să taie orice interval de date.

import pandas as pd

data_frame = data_frame.set_index('date')

df = data_frame[(data_frame.index > '2017-08-10') & (data_frame.index <= '2017-08-15')]
Abhinav Anand
Abhinav Anand
Răspuns editat 14 mai 2019 в 10:08
8
0
 Arraval
Arraval
7 februarie 2018 в 3:33
2018-02-07T15:33:38+00:00
Mai mult
Sursă
Editează
#27170340

Prefer să nu modifice "df".

O opțiune este de a prelua "index" a "start" și " end " date:

import numpy as np   
import pandas as pd

#Dummy DataFrame
df = pd.DataFrame(np.random.random((30, 3)))
df['date'] = pd.date_range('2017-1-1', periods=30, freq='D')

#Get the index of the start and end dates respectively
start = df[df['date']=='2017-01-07'].index[0]
end = df[df['date']=='2017-01-14'].index[0]

#Show the sliced df (from 2017-01-07 to 2017-01-14)
df.loc[start:end]

care duce la:

     0   1   2       date
6  0.5 0.8 0.8 2017-01-07
7  0.0 0.7 0.3 2017-01-08
8  0.8 0.9 0.0 2017-01-09
9  0.0 0.2 1.0 2017-01-10
10 0.6 0.1 0.9 2017-01-11
11 0.5 0.3 0.9 2017-01-12
12 0.5 0.4 0.3 2017-01-13
13 0.4 0.9 0.9 2017-01-14
3
0
 MattR
MattR
15 ianuarie 2019 в 9:50
2019-01-15T21:50:23+00:00
Mai mult
Sursă
Editează
#27170342

Cu testarea mea de panda versiune 0.22.0 acum puteți răspunde la această întrebare mai ușoară, cu mai lizibil codul de simplu, folosind intre.

# create a single column DataFrame with dates going from Jan 1st 2018 to Jan 1st 2019
df = pd.DataFrame({'dates':pd.date_range('2018-01-01','2019-01-01')})

Las's spui că vrei să apuca de date între 27 Noiembrie 2018 și 15 ianuarie 2019:

# use the between statement to get a boolean mask
df['dates'].between('2018-11-27','2019-01-15', inclusive=False)

0    False
1    False
2    False
3    False
4    False

# you can pass this boolean mask straight to loc
df.loc[df['dates'].between('2018-11-27','2019-01-15', inclusive=False)]

    dates
331 2018-11-28
332 2018-11-29
333 2018-11-30
334 2018-12-01
335 2018-12-02

Observa inclusive argument. foarte util atunci când doriți să fie explicit despre gama. notificare când este setat la True vom reveni Nov 27 2018 precum:

df.loc[df['dates'].between('2018-11-27','2019-01-15', inclusive=True)]

    dates
330 2018-11-27
331 2018-11-28
332 2018-11-29
333 2018-11-30
334 2018-12-01

Această metodă este, de asemenea, mai rapid decât cele menționate anterior isin metoda:

%%timeit -n 5
df.loc[df['dates'].between('2018-11-27','2019-01-15', inclusive=True)]
868 µs ± 164 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)

%%timeit -n 5

df.loc[df['dates'].isin(pd.date_range('2018-01-01','2019-01-01'))]
1.53 ms ± 305 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)

Cu toate acestea, este nu mai repede decât în prezent răspunsul acceptat, cu condiția de unutbu, numai în cazul în care masca este deja create. dar dacă masca este dinamic și are nevoie să fie redistribuit de peste si peste, metoda mea poate fi mai eficient:

# already create the mask THEN time the function

start_date = dt.datetime(2018,11,27)
end_date = dt.datetime(2019,1,15)
mask = (df['dates'] > start_date) & (df['dates'] <= end_date)

%%timeit -n 5
df.loc[mask]
191 µs ± 28.5 µs per loop (mean ± std. dev. of 7 runs, 5 loops each)
 MattR
MattR
Răspuns editat 15 ianuarie 2019 в 9:58
2
0
Comunități asemănătoare 1
Python România
Python România
125 utilizatori
Comunitatea pasionaților de Python din România.
Deschide telegram
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
Utilizatori
Toate
Nou
Populare
1
工藤 芳則
Înregistrat 6 zile în urmă
2
Ирина Беляева
Înregistrat 1 săptămână în urmă
3
Darya Arsenyeva
Înregistrat 1 săptămână în urmă
4
anyta nuam-nuam (LapuSiK)
Înregistrat 1 săptămână în urmă
5
Shuhratjon Imomkulov
Înregistrat 1 săptămână în urmă
DA
DE
EL
ES
FR
ID
IT
JA
KO
LV
NL
PT
RO
RU
SK
TR
ZH
© kzen.dev 2023
Sursă
stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire