def explode(df, lst_cols, fill_value=''): # make sure `lst_cols` is a list if lst_cols and not isinstance(lst_cols, list): lst_cols = [lst_cols] # all columns except `lst_cols` idx_cols = df.columns.difference(lst_cols) # calculate lengths of lists lens = df[lst_cols[0]].str.len() if (lens > 0).all(): # ALL lists in cells aren't empty return pd.Dataframe({ col:np.repeat(df[col].values, df[lst_cols[0]].str.len()) for col in idx_cols }).assign(**{col:np.concatenate(df[col].values) for col in lst_cols}) .loc[:, df.columns] else: # at least one list in cells is empty return pd.Dataframe({ col:np.repeat(df[col].values, df[lst_cols[0]].str.len()) for col in idx_cols }).assign(**{col:np.concatenate(df[col].values) for col in lst_cols}) .append(df.loc[lens==0, idx_cols]).fillna(fill_value) .loc[:, df.columns]用法:
In [82]: explode(df, lst_cols=list('BCDE'))Out[82]: A B C D E0 x1 v1 c1 d1 e11 x1 v2 c2 d2 e22 x2 v3 c3 d3 e33 x2 v4 c4 d4 e44 x3 v5 c5 d5 e55 x3 v6 c6 d6 e66 x4 v7 c7 d7 e77 x4 v8 c8 d8 e8


