Datas não são strings
Uma série de preços é uma série temporal: o que importa é quando cada preço ocorreu. Datas lidas de um arquivo são strings simples, e uma string não sabe que março vem depois de fevereiro nem que uma segunda-feira segue um domingo. Converta-as com pd.to_datetime e use o resultado como índice: um DatetimeIndex guarda carimbos de tempo reais que o pandas sabe ordenar, fatiar, comparar e decompor. Ordene-o sempre (sort_index()) para que a observação mais antiga venha primeiro.
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)) # TrueConstruir um calendário
Muitas vezes você precisa de datas que ninguém lhe deu: uma grade para comparar ou os dias de um backtest. pd.date_range(start, periods=n, freq="D") produz n dias corridos consecutivos, e pd.bdate_range pula os fins de semana e dá dias úteis. (Ele não sabe nada de feriados.) O argumento freq define o passo: "D" é um dia, "B" um dia útil, "h" uma hora.
# 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']Selecionar por data
Com um DatetimeIndex ordenado, .loc entende datas escritas como strings. Uma string parcial como "2026-03" seleciona o mês inteiro, "2026" o ano inteiro e "2026-03-04" um único dia. Uma fatia .loc["2026-03-04":"2026-03-06"] seleciona um intervalo e, ao contrário de uma fatia de posições, os dois extremos são incluídos. Os extremos não precisam existir nos dados: datas de fim de semana simplesmente não casam com nada, que é o que se quer ao pedir "tudo desde o dia primeiro".
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 nothingAs partes de uma data
Um DatetimeIndex expõe as partes de cada data como atributos: year, month, day, dayofweek (segunda-feira é 0, domingo é 6). Cada uma é um array com uma entrada por linha, então serve como máscara ou chave de grupo. É assim que se pergunta "quantas observações caem em cada dia da semana?" ou "o que acontece às segundas?" sem laço. Lembre-se de ordenar o índice antes: fatiar um DatetimeIndex fora de ordem pode dar resultados surpreendentes ou um erro.
# 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"] inclui o dia 6, mas com dados intradiários ele para às 00:00 do dia 6 e perde o dia inteiro. Verifique o último carimbo de tempo do resultado quando seus dados forem mais finos que um dia.pd.to_datetime(strings)cria um DatetimeIndex;sort_index()põe o mais antigo primeiro;date_rangeebdate_rangeconstroem calendários..loc["2026-03"]seleciona um mês,.loc["2026-03-04":"2026-03-06"]um intervalo com os dois extremos incluídos.index.year,index.month,index.dayofweekdão as partes de cada data, para filtrar ou agrupar sem laços.
A seguir: a reamostragem, que transforma preços diários em barras semanais, mensais ou mais finas.
Lab: o que é avaliado
- Construir uma série de preços com datas com
parse_prices25 pts - Selecionar um mês com
prices_in_month25 pts - Selecionar um intervalo de datas com
prices_between25 pts - Contar as observações por dia da semana com
count_by_weekday25 pts