Given a list of DataFrames of the form output by the function
    :func:`extract_delays`, combine them into a single DataFrame as
    follows and return the result.
    Concatenate ``delays_list`` and remove duplicate
    [route_id, trip_id, stop_sequence]
    entries by combining their non-null delay values into one entry.

    Warning: to ensure sensible output, don't include in ``delays_list``
    the same trips on different days.

    Return an empty DataFrame if ``delays_list`` is empty.

def combine_delays(delays_list):
    """
    Given a list of DataFrames of the form output by the function
    :func:`extract_delays`, combine them into a single DataFrame as
    follows and return the result.
    Concatenate ``delays_list`` and remove duplicate
    [route_id, trip_id, stop_sequence]
    entries by combining their non-null delay values into one entry.

    Warning: to ensure sensible output, don't include in ``delays_list``
    the same trips on different days.

    Return an empty DataFrame if ``delays_list`` is empty.
    """
    if not delays_list:
        return pd.DataFrame()

    f = pd.concat(delays_list)
    f = f.drop_duplicates()
    f = f.dropna(subset=['arrival_delay', 'departure_delay'],
      how='all')
    cols = ['route_id', 'trip_id', 'stop_sequence']
    f = f.sort_values(cols)
    # Backfill NaNs within each cols group.
    # Do this without groupby(), because that would create
    # too many groups.
    prev_tup = None
    new_rows = []
    dcols = ['arrival_delay', 'departure_delay']
    for __, row in f.iterrows():
        tup = row[cols].values
        if np.array_equal(tup, prev_tup):
            # A duplicate route-trip-stop row.
            # Its arrival delay or departure delay is non-null
            # by virtue of our preprocessing.
            # Use its non-null delays to backfill the previous row's delays
            # if necessary.
            if new_rows[-1][dcols].isnull().any():
                for dcol in dcols:
                    if pd.notnull(row[dcol]) and pd.isnull(new_rows[-1][dcol]):
                        new_rows[-1][dcol] = row[dcol]
        else:
            new_rows.append(row)
            prev_tup = tup
    f = pd.DataFrame(new_rows, index=range(len(new_rows)))
    return f