Δημιουργώ ένα DataFrame από ένα csv ως εξής:
stock = pd.read_csv('data_in/' + filename + '.csv', skipinitialspace=True)
Το DataFrame έχει μια στήλη ημερομηνίας. Υπάρχει τρόπος να δημιουργήσω ένα νέο DataFrame (ή απλά να αντικαταστήσω το υπάρχον) το οποίο να περιέχει μόνο γραμμές με τιμές ημερομηνίας που εμπίπτουν σε ένα καθορισμένο εύρος ημερομηνίας ή μεταξύ δύο καθορισμένων τιμών ημερομηνίας;
Υπάρχουν δύο πιθανές λύσεις:
df[start_date : end_date]
Χρησιμοποιώντας μια μάσκα boolean:
Βεβαιωθείτε ότι df['date']
είναι μια σειρά με τύπο dtype datetime64[ns]
:
df['date'] = pd.to_datetime(df['date'])
Κάντε μια μάσκα boolean. Οι ημερομηνίες start_date
και end_date
μπορούν να είναι datetime.datetime
,
np.datetime64
s, pd.Timestamp
s, ή ακόμη και συμβολοσειρές datetime:
#greater than the start date and smaller than the end date
mask = (df['date'] > start_date) & (df['date'] <= end_date)
Επιλέξτε το υποπλαίσιο δεδομένων:
df.loc[mask]
ή αναθέστε εκ νέου στο df
df = df.loc[mask]
Για παράδειγμα,
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])
αποδίδει
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
Χρησιμοποιώντας ένα DatetimeIndex:
Εάν πρόκειται να κάνετε πολλές επιλογές με βάση την ημερομηνία, μπορεί να είναι πιο γρήγορο να ορίσετε το
ημερομηνία
ως δείκτη πρώτα. Στη συνέχεια, μπορείτε να επιλέξετε γραμμές ανά ημερομηνία χρησιμοποιώντας
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'])
αποδίδει
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
Ενώ η ευρετηρίαση λίστας της Python, π.χ. seq[start:end]
περιλαμβάνει την start
αλλά όχι το end
, αντίθετα, το Pandas df.loc[start_date : end_date]
περιλαμβάνει και τα δύο τελικά σημεία στο αποτέλεσμα αν βρίσκονται στο ευρετήριο. Ωστόσο, ούτε η start_date
ούτε η end_date
πρέπει να βρίσκονται στο ευρετήριο.
Σημειώστε επίσης ότι η pd.read_csv
έχει μια παράμετρο parse_dates
την οποία θα μπορούσατε να χρησιμοποιήσετε για να αναλύσετε τη στήλη date
ως datetime64
. Έτσι, αν χρησιμοποιήσετε την parse_dates
, δεν θα χρειαστεί να χρησιμοποιήσετε την df['date'] = pd.to_datetime(df['date'])
.
Θεωρώ ότι η καλύτερη επιλογή θα είναι να χρησιμοποιήσετε τους άμεσους ελέγχους αντί να χρησιμοποιήσετε τη λειτουργία loc:
df = df[(df['date'] > '2000-6-1') & (df['date'] <= '2000-6-10')]
Λειτουργεί για μένα.
Σημαντικό ζήτημα με τη συνάρτηση loc με μια φέτα είναι ότι τα όρια θα πρέπει να υπάρχουν στις πραγματικές τιμές, αν όχι αυτό θα οδηγήσει σε KeyError.
Μπορείτε να χρησιμοποιήσετε τη μέθοδο isin
στη στήλη date
ως εξής
df[df["date"].isin(pd.date_range(start_date, end_date))]
Σημείωση: Αυτό λειτουργεί μόνο με ημερομηνίες (όπως ζητάει η ερώτηση) και όχι με χρονοσφραγίδες.
Παράδειγμα:
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
το οποίο δίνει
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