Un arreglo con etiquetas
Una Series de pandas es un arreglo unidimensional en el que cada valor tiene una etiqueta, guardada en el índice de la Series. En lugar de recordar que la posición 1 es Microsoft, pides prices["MSFT"]. Una Series tiene un name, un dtype como un arreglo NumPy y admite la misma aritmética sobre arreglos completos, así que prices * 2, prices.mean() y prices > 180 funcionan. Por convención se importa pandas como import pandas as pd; se construye sobre NumPy, que viste en los temas 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}))Alineación: las operaciones emparejan etiquetas, no posiciones
Al combinar dos Series, pandas las alinea primero por etiqueta. Las etiquetas presentes en una sola dan NaN (not a number, la marca de valor ausente) en el resultado, cuyo índice es la unión de ambos índices. Es justo lo que quieres para posiciones en cuentas distintas. Usa a.add(b, fill_value=0) para tratar una etiqueta ausente como cero en lugar de producir NaN. La lectura por etiqueta también difiere de NumPy: s["MSFT"] es por etiqueta, mientras s.iloc[1] es por posición, y una etiqueta inexistente lanza 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, clasificar y rebasar
s.sort_values(ascending=False) ordena por valor llevándose las etiquetas, s.sort_index() ordena por etiqueta y s.abs() toma valores absolutos. Ordenar más cortar encuentra los mayores movimientos: r.abs().sort_values(ascending=False).index[:3] da las tres etiquetas con mayor rendimiento absoluto. Para comparar activos que cotizan a niveles de precio distintos, rebasa cada uno a 100 al inicio: s / s.iloc[0] * 100, que conserva el índice y el nombre. Los valores ausentes (NaN) los omiten sum, mean y similares; s.isna() los 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" y "aapl " son etiquetas distintas, así que una errata produce en silencio filas NaN; limpia las etiquetas (strip, upper) antes de combinar. Un índice puede tener duplicados, y entonces s["AAPL"] devuelve una Series en lugar de un valor; comprueba s.index.is_unique en datos que deben tener un valor por etiqueta. Las operaciones devuelven Series nuevas y dejan intacta la original, que es el comportamiento que comprueban las pruebas del lab.pd.Series(values, index=labels, name=...); leer por etiquetas["A"]o posicións.iloc[0].- Las operaciones se alinean por etiquetas (índice unión,
NaNsi falta);a.add(b, fill_value=0)trata un hueco como 0. sort_values,abs,idxmax,s / s.iloc[0] * 100; los resultados son Series nuevas y la original no cambia.
A continuación: DataFrames de pandas, tablas hechas de Series que comparten un índice.
Lab: qué se califica
- Etiquetar precios por símbolo con
price_series25 pts - Sumar dos cuentas por etiqueta con
total_exposure25 pts - Encontrar los mayores movimientos con
top_movers25 pts - Poner cada precio en base 100 con
rebase_to_10025 pts