从单个df派生多个df,使得每个df都没有NaN值

时间:2020-04-07 05:25:18

标签: python pandas dataframe

我要转换此表

0   thg   John     3.0
1   thg  James     4.0
2   mol    NaN     5.0
3   mol    NaN     NaN
4   lob    NaN     NaN

在以下表格中

df1
movie   name  rating
0   thg   John     3.0
1   thg  James     4.0

df2
    movie  rating
2   mol     5.0

df3
    movie
3   mol  
4   lob  

每个数据帧都没有Nan值的地方,还告诉方法是否需要针对空白值而不是Nan进行分离。

2 个答案:

答案 0 :(得分:3)

我认为新目标DataFrame的开始不应该发生 仅当 NaN 值的 number 值发生变化时(与 前一行),但当此数字相同时, NaN 值在不同的列中。

所以我提出以下公式:

dfs = [g.dropna(how='all',axis=1) for _,g in
    df.groupby(df.isna().ne(df.isna().shift()).any(axis=1).cumsum())]

您可以打印正在运行的部分DataFrame(任意数量):

n = 0
for grp in dfs:
    print(f'\ndf No {n}:\n{grp}')
    n += 1

当您添加时,我的解决方案相对于其他解决方案的优势显而易见 到源DataFrame的另一行包含:

5   NaN    NaN    3.0

它还包含 1 个非空值(如前两行)。 另一种解决方案会将所有这些行视为一个部分DataFrame 包含:

  movie  rating
3   mol     NaN
4   lob     NaN
5   NaN     3.0
如您所见,

具有 NaN 值的,而我的解决方案将这些值分开 排成2个单独的DataFrame,没有任何 NaN

答案 1 :(得分:2)

使用groupby和dropna创建dfs列表:

dfs = [g.dropna(how='all',axis=1) for _,g in df.groupby(df.isna().sum(1))]
print(dfs[0],'\n\n',dfs[1],'\n\n',dfs[2])

或字典:

d = {f"df{e+1}": g[1].dropna(how='all',axis=1) 
       for e,g in enumerate(df.groupby(df.isna().sum(1)))}
print(d['df1'],'\n\n',d['df2'],'\n\n',d['df3']) #read the keys of d

  movie   name  rating
0   thg   John     3.0
1   thg  James     4.0 

   movie  rating
2   mol     5.0 

   movie
3   mol
4   lob