def convert_listlike_cols_to_str(df, list_cols, convert_nan=False, nanreplacement = "[]"):
    """ Convert listlike values in pandas DataFrame to stringlists.

    Writing a DataFrame to excel and csv raises errors due to presence of listlike or arraylike data.
    Here, all listlike and arraylike data is converted to a "stringlist"

    Parameters
    ----------
    df : pandas DataFrame
        Pandas DataFrame where some values are listlike or arraylike
    list_cols : list
        List of columns that contain listlike/arraylike should be converted to stringlists
    convert_nan : bool
        Whether np.nan values will be converted
    nanreplacement : string
        String to replace np.nan with. Default is a string representing an empty list. "[]"

    Returns
    ----------
    df : pandas DataFrame
        DataFrame with listlike and arraylike converted to stringlists

    Note:
    ----------
    # Convert individual stringlist back to a numpy array as follows
    np.array(ast.literal_eval(stringlist))
    # convert a column of stringlists back to arrays as follows
    df.loc[:,"x"] = df.loc[:,"x"].apply(lambda x : np.array(ast.literal_eval(x)))
    """
    for col in list_cols:
        if col in df:
            # convert each np.array to a list, and then a stringlist
            series = df[col].dropna()
            # check if the series is empty (no data)
            if series.empty == False:
                example_data1 = series[0]
                # if the datatype is a numpy array or pandas series, convert to a list
                if "ndarray" in str(type(example_data1)) or "Series" in str(type(example_data1)):
                    df[col] = series.apply(lambda x: list(x))
                example_data2 = df[col].dropna()[0]
                # check that the first nonnan datapoint is now a list
                if "list" in str(type(example_data2)):
                    df[col] = df[col].dropna().apply(lambda x: str(x))
                else:
                    raise TypeError("datatype for col {a}, ({b}) is not listlike".format(a=col, b=str(type(example_data2))))
                # if desired, convert np.nan to empty stringlists
                if convert_nan == True:
                    df[col] = df[col].fillna(nanreplacement)
            else:
                #do nothing. There is no listlike data in the column, because all values are empty
                pass
        else:
            raise KeyError("The column {} is not in the dataframe".format(col))
    return df