def get_series_df_from_panel(
    df_panel,
    series,
    time_index_freq,
    time_format="%Y-%m-%d",
    time_field="indice_tiempo",
    series_id_field="serie_id",
    values_field="valor",
):
    """Convierte tabla con id, fecha y valor en distribución de TS.

    Args:
        df_panel (pd.DataFrame): Tabla con columnas de id de series, fecha
            y valor de observaciones.
        series (dict): Donde los keys son "field_id" de series y los values
            son "field_title" de las series.
        time_field (str): Campo que tiene la fecha.
        time_format (str): Formato en el que hay que parsear la fecha.
        series_id_field (str): Campo que tiene el id de la serie.
        values_field (str): Campo que tiene los valores de las observaciones.

    return: pd.DataFrame
    """

    # parsea el campo de fechas al tipo datetime
    df_panel[time_field] = pd.to_datetime(df_panel[time_field],
                                          format=time_format)

    # se queda solo con las series elegidas
    df = df_panel[df_panel[series_id_field].isin(series.keys())]

    # construye un período continuo para el índice de tiempo, el más largo
    period_range = pd.date_range(
        min(df.indice_tiempo),
        max(df.indice_tiempo),
        freq=freq_iso_to_pandas(time_index_freq),
    )

    # cambia ids por titulos que sean nombres de campos al pivotar
    df["serie_id"] = df.serie_id.apply(series.get)

    # convierte el panel en una tabla de series de tiempo
    data = df.pivot_table(columns="serie_id",
                          index="indice_tiempo",
                          values="valor")

    # convierte el indice de tiempo a comienzos de periodos
    try:
        data.index = data.index.to_period(
            freq=freq_iso_to_pandas(time_index_freq, "start")).to_timestamp()
    except Exception as e:
        data.index = data.index.to_period(
            freq=freq_iso_to_pandas(time_index_freq, "end")).to_timestamp()

    # completa indice de tiempo con periodos faltante para que sea continuo
    df_series = pd.DataFrame(index=period_range, data=data)

    return df_series
示例#2
0
    def init_df(self, distribution, fields):
        """Inicializa el DataFrame del CSV de la distribución pasada,
        seteando el índice de tiempo correcto y validando las columnas
        dentro de los datos

        Args:
            distribution (Distribution): modelo de distribución válido
            fields (dict): diccionario con estructura titulo: serie_id
        """

        df = read_distribution_csv_as_df(distribution)

        self.drop_null_or_missing_fields_from_df(df, fields)
        identifiers = [fields[name] for name in df.columns]

        data = df.values
        freq = freq_iso_to_pandas(
            get_time_index_periodicity(distribution, fields))
        new_index = pd.date_range(df.index[0], df.index[-1], freq=freq)

        # Chequeo de series de días hábiles (business days)
        if freq == constants.DAILY_FREQ and new_index.size > df.index.size:
            new_index = pd.date_range(df.index[0],
                                      df.index[-1],
                                      freq=constants.BUSINESS_DAILY_FREQ)

        return pd.DataFrame(index=new_index, data=data, columns=identifiers)
示例#3
0
def validate_df_shape(df, distrib_meta, _catalog):
    periodicity = None
    for field in distrib_meta["field"]:
        if field.get("specialType") == "time_index":
            periodicity = field.get("specialTypeDetail")

    freq = freq_iso_to_pandas(periodicity)
    new_index = pd.date_range(df.index[0], df.index[-1], freq=freq)
    columns = df.columns
    data = np.array(df)
    try:
        pd.DataFrame(index=new_index, data=data, columns=columns)

    except ValueError:
        if freq == "D":
            freq = "B"
            new_index = pd.date_range(df.index[0], df.index[-1], freq=freq)
            try:
                pd.DataFrame(index=new_index, data=data, columns=columns)
                return

            except ValueError:
                pass

        raise ce.DistributionBadDataError(
            distrib_meta["identifier"],
            df.index[0],
            df.index[-1],
            periodicity,
            len(new_index),
            len(data),
        )
示例#4
0
    def init_df(self, distribution, fields):
        """Inicializa el DataFrame del CSV de la distribución pasada,
        seteando el índice de tiempo correcto y validando las columnas
        dentro de los datos

        Args:
            distribution (Distribution): modelo de distribución válido
            fields (dict): diccionario con estructura titulo: serie_id
        """

        df = read_distribution_csv(distribution)

        # Borro las columnas que no figuren en los metadatos
        for column in df.columns:
            if column not in fields:
                df.drop(column, axis='columns', inplace=True)
        columns = [fields[name] for name in df.columns]

        data = df.values
        freq = freq_iso_to_pandas(
            get_time_index_periodicity(distribution, fields))
        new_index = pd.date_range(df.index[0], df.index[-1], freq=freq)

        # Chequeo de series de días hábiles (business days)
        if freq == constants.DAILY_FREQ and new_index.size > df.index.size:
            new_index = pd.date_range(df.index[0],
                                      df.index[-1],
                                      freq=constants.BUSINESS_DAILY_FREQ)

        return pd.DataFrame(index=new_index, data=data, columns=columns)
def generate_df_time_index(df: pd.DataFrame, time_index: Field):
    periodicity = get_distribution_time_index_periodicity(time_index)
    freq = freq_iso_to_pandas(periodicity)
    new_index = pd.date_range(df.index[0], df.index[-1], freq=freq)

    # Chequeo de series de días hábiles (business days)
    if freq == constants.DAILY_FREQ and new_index.size > df.index.size:
        new_index = pd.date_range(df.index[0],
                                  df.index[-1],
                                  freq=constants.BUSINESS_DAILY_FREQ)
    return new_index