التواريخ ليست نصوصًا
سلسلة الأسعار سلسلة زمنية: المهم هو متى حدث كل سعر. والتواريخ المقروءة من ملف نصوص عادية، والنص لا يعرف أن مارس يأتي بعد فبراير ولا أن الاثنين يلي الأحد. حوّلها بـ pd.to_datetime واستخدم الناتج فهرسًا: يحمل DatetimeIndex طوابع زمنية حقيقية تستطيع pandas ترتيبها وتقطيعها ومقارنتها وتفكيكها. رتّبه دائمًا (sort_index()) ليأتي أقدم رصد أولًا.
import pandas as pd
raw_dates = ["2026-03-04", "2026-03-02", "2026-03-03"] # strings, in a messy order
closes = [102.0, 100.0, 101.0]
series = pd.Series(closes, index=pd.to_datetime(raw_dates), name="close").sort_index()
print(series)
# 2026-03-02 100.0
# 2026-03-03 101.0
# 2026-03-04 102.0
# Name: close, dtype: float64
print(isinstance(series.index, pd.DatetimeIndex)) # Trueبناء تقويم
كثيرًا ما تحتاج تواريخ لم يعطك إياها أحد: شبكة للمقارنة أو أيام اختبار رجعي. ينتج pd.date_range(start, periods=n, freq="D") عدد n من الأيام التقويمية المتتالية، ويتجاوز pd.bdate_range عطلات نهاية الأسبوع ويعطي أيام عمل. (ولا يعرف شيئًا عن العطل الرسمية.) ويحدد الوسيط freq الخطوة: "D" يوم و"B" يوم عمل و"h" ساعة.
# Four calendar days, then six business days (the weekend is skipped)
print(pd.date_range("2026-03-01", periods=4, freq="D").strftime("%a %d %b").tolist())
# ['Sun 01 Mar', 'Mon 02 Mar', 'Tue 03 Mar', 'Wed 04 Mar']
days = pd.bdate_range("2026-02-26", periods=6)
print(days.strftime("%a %d %b").tolist())
# ['Thu 26 Feb', 'Fri 27 Feb', 'Mon 02 Mar', 'Tue 03 Mar', 'Wed 04 Mar', 'Thu 05 Mar']الاختيار بالتاريخ
مع DatetimeIndex مرتّب يفهم .loc التواريخ المكتوبة نصوصًا. يختار النص الجزئي مثل "2026-03" الشهر كله، و"2026" السنة كلها، و"2026-03-04" يومًا واحدًا. ويختار التقطيع .loc["2026-03-04":"2026-03-06"] نطاقًا، وعلى عكس تقطيع المواضع يشمل الطرفين. ولا يلزم أن يوجد الطرفان في البيانات: تواريخ نهاية الأسبوع لا تطابق شيئًا ببساطة، وهذا ما تريده حين تطلب «كل شيء منذ أول الشهر».
prices = pd.Series(
[float(i) for i in range(20)],
index=pd.bdate_range("2026-02-23", periods=20), # Mon 23 Feb ... Fri 20 Mar
)
print(len(prices.loc["2026-03"])) # 15 the business days of March in the data
print(prices.loc["2026-03-04"]) # 7.0 a single day
print(prices.loc["2026-03-04":"2026-03-06"])
# 2026-03-04 7.0
# 2026-03-05 8.0
# 2026-03-06 9.0
# Freq: B, dtype: float64
print(prices.loc["2026-03-01":"2026-03-03"].tolist()) # [5.0, 6.0] Sunday the 1st matches nothingأجزاء التاريخ
يعرض DatetimeIndex أجزاء كل تاريخ كخصائص: year وmonth وday وdayofweek (الاثنين 0 والأحد 6). وكل منها مصفوفة بعنصر لكل صف، فتصلح قناعًا أو مفتاح مجموعة. هكذا تسأل «كم رصدًا يقع في كل يوم من الأسبوع؟» أو «ماذا يحدث أيام الاثنين؟» دون حلقة. وتذكّر أن ترتّب الفهرس أولًا: تقطيع DatetimeIndex غير مرتّب قد يعطي نتائج مفاجئة أو خطأً.
# The parts of the dates, one entry per row
print(prices.index.dayofweek[:7].tolist()) # [0, 1, 2, 3, 4, 0, 1] Monday is 0
print(prices.index.month[:7].tolist()) # [2, 2, 2, 2, 2, 3, 3]
# How many observations fall on each weekday?
print(prices.groupby(prices.index.dayofweek).size().to_dict()) # {0: 4, 1: 4, 2: 4, 3: 4, 4: 4}
# What do the Mondays look like?
print(prices[prices.index.dayofweek == 0].tolist()) # [0.0, 5.0, 10.0, 15.0].loc["2026-03-04":"2026-03-06"] يوم السادس، لكن مع بيانات خلال اليوم يتوقف عند 00:00 من السادس فيفقد اليوم كله. افحص آخر طابع زمني في النتيجة حين تكون بياناتك أدق من يوم.pd.to_datetime(strings)تنشئ DatetimeIndex؛ وsort_index()تضع الأقدم أولًا؛ وdate_rangeوbdate_rangeتبنيان تقاويم..loc["2026-03"]يختار شهرًا، و.loc["2026-03-04":"2026-03-06"]نطاقًا يشمل الطرفين.index.yearوindex.monthوindex.dayofweekتعطي أجزاء كل تاريخ للترشيح أو التجميع بلا حلقات.
التالي: إعادة التقطيع، أي تحويل الأسعار اليومية إلى أشرطة أسبوعية أو شهرية أو أدق.
المختبر: ما الذي يُقيَّم
- ابنِ سلسلة أسعار مؤرَّخة باستخدام
parse_prices25 نقطة - اختر شهرًا واحدًا باستخدام
prices_in_month25 نقطة - اختر نطاقًا من التواريخ باستخدام
prices_between25 نقطة - عُدّ الملاحظات لكل يوم من الأسبوع باستخدام
count_by_weekday25 نقطة