def find_joins(df, ids, downstream_col="downstream", upstream_col="upstream", expand=0):
    """Find the joins for a given segment id in a joins table.

    Parameters
    ----------
    df : DataFrame
        data frame containing the joins
    ids : list-like
        ids to lookup in upstream or downstream columns
    downstream_col : str, optional (default "downstream")
        name of downstream column
    upstream_col : str, optional (default "upstream")
        name of upstream column
    expand : positive int, optional (default 0)
        If > 0, will expand the search to "expand" degrees from the original ids.
        E.g., if expand is 2, this will return all nonzero joins that are within 2
        joins of the original set of ids.

    Returns
    -------
    Joins that have the id as an upstream or downstream.
    """
    out = df.loc[(df[upstream_col].isin(ids)) | (df[downstream_col].isin(ids))]

    # find all upstream / downstream joins of ids returned at each iteration
    for i in range(expand):
        next_ids = (set(out[upstream_col]) | set(out[downstream_col])) - {0}
        out = df.loc[
            (df[upstream_col].isin(next_ids)) | (df[downstream_col].isin(next_ids))
        ]

    return out