File size: 2,381 Bytes
8f074bc |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
import pandas as pd
from typing import Sequence, Any
import re
_NEG_COLOR = "red"
def format_large_number(n, decimals=2):
if n >= 1e12:
return f'{n / 1e12:.{decimals}f} T'
elif n >= 1e9:
return f'{n / 1e9:.{decimals}f} B'
elif n >= 1e6:
return f'{n / 1e6:.{decimals}f} M'
else:
return str(n)
def format_results(df: pd.DataFrame, rename_columns: dict) -> pd.DataFrame:
# Índice 100
if "ind_sust" in df.columns:
df["ind_sust"] = df["ind_sust"].apply(lambda x: "-" if pd.isna(x) else int(round(x * 100, 0)))
# 1 decimal
for col in ["trailingPE", "beta"]:
if col in df.columns:
df[col] = df[col].apply(lambda x: "-" if pd.isna(x) else f"{x:.1f}")
# 2 decimales
if "Search dist." in df.columns:
df["Search dist."] = df["Search dist."].apply(lambda n: "-" if pd.isna(n) else f"{n:.2f}")
# Cantidades monetarias grandes
if "marketCap" in df.columns:
df["marketCap"] = df["marketCap"].apply(lambda n: "-" if pd.isna(n) else format_large_number(n, 1))
# Porcentajes 1 decimal
for col in ["ret_365", "revenueGrowth"]:
if col in df.columns:
df[col] = df[col].apply(lambda x: "-" if pd.isna(x) or x == 0 else f"{(x * 100):.1f}%")
# Porcentajes 1 decimal (porcentaje numérico en fuente)
for col in ["dividendYield"]:
if col in df.columns:
df[col] = df[col].apply(lambda x: "-" if pd.isna(x) else f"{round(x, 1)}%")
# Volatilidad
if "vol_365" in df.columns:
df["vol_365"] = df["vol_365"].apply(lambda x: "-" if pd.isna(x) or x == 0 else f"{x:.4f}")
# Devolvemos el dataframe con los nombres de columnas renombrados
return df.rename(columns=rename_columns)
def random_ticker(df: pd.DataFrame) -> str:
return df["ticker"].sample(n=1).values[0]
def styler_negative_red(df: pd.DataFrame, cols: list[str] | None = None):
"""
Returns a Styler that paints negative numeric values in *cols*.
Columns absent in *df* are ignored.
"""
cols = [c for c in (cols or df.columns) if c in df.columns]
def _style(v):
try:
num = float(re.sub(r"[ %,TMB]", "", str(v)))
if num < 0:
return f"color:{_NEG_COLOR}"
except ValueError:
pass
return ""
return df.style.applymap(_style, subset=cols) |