使用 pandas 融化列中不均匀的数据并忽略 NaN

JAG*_*024 3 python dataframe melt pandas

一定有一种优雅的方法来做到这一点,但我还没有找到。我有一个大数据框,看起来像这样:

df
    Name    0           1           2        3      4   
1   apple   2016 W1     NaN         NaN      NaN    NaN 
2   orange  2016 W1     2017 W2     NaN      NaN    NaN 
3   banana  2016 W2     2017 W3     NaN      NaN    NaN  
4   pear    2016 W3     2016 W4     2016 W5  NaN    NaN
6   melon   2016 W2     2016 W4     2017 W5  2017 W6 2017 W7
Run Code Online (Sandbox Code Playgroud)

我想融合数据,使得只有两列nameweek。所以结果应该是这样的:

df_result

    Name    week       
    apple   2016 W1     
    orange  2016 W1
    orange  2017 W2     
    banana  2016 W2 
    banana  2017 W3
    pear    2016 W3    
    pear    2016 W4    
    ... etc. 
Run Code Online (Sandbox Code Playgroud)

我所坚持的是如何忽略 NaN 值,同时确保不丢失任何值。

当我这样做时,pd.melt(df, id_vars=['Name'])我不确定结果是否是我想要的。

WeN*_*Ben 7

操作1

df.melt('Name').dropna().drop('variable',1)
Out[62]: 
      Name    value
0    apple  2016 W1
1   orange  2016 W1
2   banana  2016 W2
3     pear  2016 W3
4    melon  2016 W2
6   orange  2017 W2
7   banana  2017 W3
8     pear  2016 W4
9    melon  2016 W4
13    pear  2016 W5
14   melon  2017 W5
19   melon  2017 W6
24   melon  2017 W7
Run Code Online (Sandbox Code Playgroud)

操作2

df.set_index('Name').stack().reset_index().drop('level_1',1)
Out[66]: 
      Name        0
0    apple  2016 W1
1   orange  2016 W1
2   orange  2017 W2
3   banana  2016 W2
4   banana  2017 W3
5     pear  2016 W3
6     pear  2016 W4
7     pear  2016 W5
8    melon  2016 W2
9    melon  2016 W4
10   melon  2017 W5
11   melon  2017 W6
12   melon  2017 W7
Run Code Online (Sandbox Code Playgroud)

操作3

pd.DataFrame({'Name':df.Name.tolist()*5,'Value':np.concatenate(df.iloc[:,1:].values)}).dropna()
Out[69]: 
      Name    Value
0    apple  2016 W1
5    apple  2016 W1
6   orange  2017 W2
10   apple  2016 W2
11  orange  2017 W3
15   apple  2016 W3
16  orange  2016 W4
17  banana  2016 W5
20   apple  2016 W2
21  orange  2016 W4
22  banana  2017 W5
23    pear  2017 W6
24   melon  2017 W7
Run Code Online (Sandbox Code Playgroud)