Um array com rótulos
Uma Series do pandas é um array unidimensional em que cada valor tem um rótulo, guardado no índice da Series. Em vez de lembrar que a posição 1 é a Microsoft, você pede prices["MSFT"]. Uma Series tem um name, um dtype como um array NumPy e aceita a mesma aritmética sobre arrays inteiros, então prices * 2, prices.mean() e prices > 180 funcionam. Por convenção importa-se o pandas com import pandas as pd; ele é construído sobre o NumPy, visto nos tópicos anteriores.
import pandas as pd
prices = pd.Series([184.25, 410.2, 171.0], index=["AAPL", "MSFT", "GOOG"], name="price")
print(prices)
# AAPL 184.25
# MSFT 410.20
# GOOG 171.00
# Name: price, dtype: float64
print(prices["AAPL"], prices.iloc[1]) # 184.25 410.2 by label, by position
print(prices.index.tolist()) # ['AAPL', 'MSFT', 'GOOG']
print(prices[prices > 180]) # keeps AAPL and MSFT, labels intact
print(prices.mean(), prices.idxmax()) # 255.15 MSFT
# A dict also builds a Series: keys become the index
print(pd.Series({"AAPL": 1, "MSFT": 2}))Alinhamento: as operações casam rótulos, não posições
Ao combinar duas Series, o pandas as alinha primeiro por rótulo. Os rótulos presentes em apenas uma dão NaN (not a number, a marca de valor ausente) no resultado, cujo índice é a união dos dois índices. É exatamente o que você quer para posições mantidas em contas diferentes. Use a.add(b, fill_value=0) para tratar um rótulo ausente como zero em vez de produzir NaN. A leitura por rótulo também difere do NumPy: s["MSFT"] é por rótulo, enquanto s.iloc[1] é por posição, e um rótulo inexistente gera KeyError.
import pandas as pd
a = pd.Series([100, 200], index=["AAPL", "MSFT"])
b = pd.Series([50, 10], index=["MSFT", "GOOG"])
print(a + b)
# AAPL NaN
# GOOG NaN
# MSFT 250.0
print(a.add(b, fill_value=0))
# AAPL 100.0
# GOOG 10.0
# MSFT 250.0
# Selecting by a list of labels, and asking for one that is missing
prices = pd.Series([184.25, 410.2], index=["AAPL", "MSFT"])
print(prices.reindex(["MSFT", "TSLA"]).tolist()) # [410.2, nan]Ordenar, classificar e rebasear
s.sort_values(ascending=False) ordena por valor levando os rótulos, s.sort_index() ordena por rótulo e s.abs() pega valores absolutos. Ordenar mais fatiar acha os maiores movimentos: r.abs().sort_values(ascending=False).index[:3] dá os três rótulos com maior retorno absoluto. Para comparar ativos que negociam em níveis de preço diferentes, rebaseie cada um a 100 no início: s / s.iloc[0] * 100, que mantém o índice e o nome. Valores ausentes (NaN) são ignorados por sum, mean e afins; s.isna() os marca.
import pandas as pd
r = pd.Series([0.01, -0.03, 0.02], index=["x", "y", "z"])
print(r.abs().sort_values(ascending=False))
# y 0.03
# z 0.02
# x 0.01
# dtype: float64
prices = pd.Series([184.25, 410.2, 171.0], index=["AAPL", "MSFT", "GOOG"], name="price")
print(prices / prices.iloc[0] * 100) # rebased to 100 at the first value
# AAPL 100.000000
# MSFT 222.632293
# GOOG 92.808684
# Name: price, dtype: float64
gappy = pd.Series([1.0, None, 3.0])
print(gappy.sum(), gappy.mean(), gappy.isna().tolist()) # 4.0 2.0 [False, True, False]import pandas as pd
# A stray space and a lower-case letter make "the same" symbol two labels
raw = pd.Series([1, 2], index=["AAPL", "aapl "])
print(raw.index.is_unique) # True: they look different
raw.index = raw.index.str.strip().str.upper() # clean the labels
print(raw.index.is_unique) # False: now both are "AAPL"
print(raw["AAPL"].tolist()) # [1, 2] a duplicate label returns a Series
merged = raw.groupby(level=0).sum() # combine duplicates (groupby comes soon)
print(merged.to_dict()) # {'AAPL': 3}"AAPL" e "aapl " são rótulos diferentes, então um erro de digitação produz em silêncio linhas NaN; limpe os rótulos (strip, upper) antes de combinar. Um índice pode ter duplicatas, e então s["AAPL"] devolve uma Series em vez de um valor; confira s.index.is_unique em dados que devem ter um valor por rótulo. As operações devolvem novas Series e deixam a original intacta, comportamento que os testes do lab verificam.pd.Series(values, index=labels, name=...); ler por rótulos["A"]ou posiçãos.iloc[0].- As operações se alinham por rótulos (índice união,
NaNse faltar);a.add(b, fill_value=0)trata uma lacuna como 0. sort_values,abs,idxmax,s / s.iloc[0] * 100; os resultados são Series novas e a original não muda.
A seguir: DataFrames do pandas, tabelas feitas de Series que compartilham um índice.
Lab: o que é avaliado
- Rotular preços por símbolo com
price_series25 pts - Somar duas contas por rótulo com
total_exposure25 pts - Encontrar os maiores movimentos com
top_movers25 pts - Colocar cada preço na base 100 com
rebase_to_10025 pts