如何在删除空值的同时合并N个非数字列?

时间:2018-09-07 07:12:51

标签: python pandas

以这个问题Combining columns and removing NaNs Pandas为基础,

我有一个看起来像这样的数据框:

col     x       y        z

a1      a       NaN      NaN
a2      NaN     b        NaN
a3      NaN     c        NaN
a4      NaN     NaN      d
a5      NaN     e        NaN
a6      f       NaN      NaN
a7      g       NaN      NaN
a8      NaN     NaN      NaN

单元格值是字符串,NaN是任意空值。

我想合并这些列,从而添加一个新的合并列:

col  w

a1   a
a2   b
a3   c
a4   d
a5   e
a6   f
a7   g
a8   NaN

上述问题中提出的优雅解决方案使用

df['w']=df[['x','y','z']].sum(axis=1)

但总和不适用于非数字值。

在这种情况下,对于字符串,如何将列合并为单个列?

您可以假设:

  1. 每行中只有xyz中的一个为非空。
  2. 必须按名称引用各个列(因为它们是数据框中所有可用列的子集)。
  3. 通常,子集中有N列,而不仅仅是3列。
  4. 希望iloc / for循环没有用:\

更新:(对已经给出答案的人表示歉意:\)

  1. 我添加了最后一行,其中每一列都包含NaN,我希望合并后的行能够反映这一点。谢谢+抱歉!

一如既往地感谢所有帮助

3 个答案:

答案 0 :(得分:2)

这是另一个解决方案:

df['res'] = df.fillna('').sum(1).replace('', np.nan)

结果是

       x    y    z  res
col                    
a1     a  NaN  NaN    a
a2   NaN    b  NaN    b
a3   NaN    c  NaN    c
a4   NaN  NaN    d    d
a5   NaN    e  NaN    e
a6     f  NaN  NaN    f
a7     g  NaN  NaN    g
a8   NaN  NaN  NaN  NaN

答案 1 :(得分:1)

我认为您需要:

s = df[['x','y','z']]
df['w'] = s.values[s.notnull()]
df[['col','w']]

或者在修改问题之后:

df['w'] = pd.DataFrame(df[['x','y','z']].apply(lambda x: x.values[x.notnull()],axis=1).tolist())
df[['col','w']].fillna(np.nan)

哪个给

    col w
0   a1  a
1   a2  b
2   a3  c
3   a4  d
4   a5  e
5   a6  f
6   a7  g
7   a8  NaN

答案 2 :(得分:0)

您必须应用自定义函数,而不是一般的总和。 例如,此示例适用于您的示例:

import numpy as np
f = lambda x: x[x.notnull()][0] if any(x.notnull()) else np.nan
df['w'] = df[list('xyz')].apply(f, axis=1)