Ich erstelle einen DataFrame aus einer csv-Datei wie folgt:
stock = pd.read_csv('data_in/' + filename + '.csv', skipinitialspace=True)
Der DataFrame hat eine Datumsspalte. Gibt es eine Möglichkeit, einen neuen DataFrame zu erstellen (oder einfach den vorhandenen zu überschreiben), der nur Zeilen mit Datumswerten enthält, die in einen bestimmten Datumsbereich oder zwischen zwei bestimmte Datumswerte fallen?
Es gibt zwei mögliche Lösungen:
df.loc[mask]
df[start_date : end_date]
Verwendung einer booleschen Maske:
Stellen Sie sicher, dass df['date']
eine Serie mit dem Typ datetime64[ns]
ist:
df['date'] = pd.to_datetime(df['date'])
Erstelle eine boolesche Maske. start_dateund
end_datekönnen
datetime.datetimesein,
np.datetime64,
pd.Timestamp`, oder auch datetime-Strings sein:
#greater than the start date and smaller than the end date
mask = (df['date'] > start_date) & (df['date'] <= end_date)
Wählen Sie den Sub-DataFrame:
df.loc[mask]
oder neu zuordnen zu df
df = df.loc[mask]
Zum Beispiel,
numpy als np importieren
importiere pandas als pd
df = pd.DataFrame(np.random.random((200,3)))
df['Datum'] = pd.date_range('2000-1-1', periods=200, freq='D')
mask = (df['Datum'] > '2000-6-1') & (df['Datum'] <= '2000-6-10')
print(df.loc[mask])
```
ergibt
```
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
```
----------
**Verwendung eines [DatetimeIndex](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#partial-string-indexing)**:
Wenn Sie viele Selektionen nach Datum durchführen wollen, kann es schneller sein, die Spalte
Datum"-Spalte zuerst als Index zu setzen. Dann können Sie Zeilen nach Datum auswählen, indem Sie
`df.loc[start_date:end_date]`.
```` python
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.random((200,3)))
df['Datum'] = pd.date_range('2000-1-1', periods=200, freq='D')
df = df.set_index(['Datum'])
print(df.loc['2000-6-1':'2000-6-10'])
```
ergibt
```
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
```
Während die Python-Listenindizierung, z.B. `seq[start:end]` zwar `start`, aber nicht `end` einschließt, schließt Pandas `df.loc[start_date : end_date]` im Gegensatz dazu *beide* Endpunkte in das Ergebnis ein, wenn sie im Index stehen. Weder `start_date` noch `end_date` müssen jedoch im Index stehen.
----------
Beachten Sie auch, dass [pd.read_csv` einen `parse_dates`-Parameter] (http://pandas.pydata.org/pandas-docs/dev/generated/pandas.io.parsers.read_csv.html) hat, den Sie verwenden können, um die Spalte `date` als `datetime64` zu parsen. Wenn Sie also `parse_dates` verwenden, müssen Sie nicht `df['date'] = pd.to_datetime(df['date'])` verwenden.
Meiner Meinung nach ist es am besten, die Direktprüfungen zu nutzen, anstatt die Loc-Funktion zu verwenden:
df = df[(df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')]
Das funktioniert bei mir.
Das Hauptproblem bei der Loc-Funktion mit einem Slice ist, dass die Grenzen in den tatsächlichen Werten vorhanden sein sollten, wenn nicht, führt dies zu einem KeyError.
Sie können die Methode "isin" für die Spalte "date" wie folgt verwenden df[df["Datum"].isin(pd.date_range(start_date, end_date))]`
Anmerkung: Dies funktioniert nur mit Datumsangaben (wie in der Frage gefordert) und nicht mit Zeitstempeln.
Beispiel:
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
Das ergibt
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