【问题标题】:How to combine multiple dataframe columns into one given each column has nan values给定每列具有nan值的情况下,如何将多个数据框列合并为一个
【发布时间】:2021-06-16 16:08:08
【问题描述】:

我有一个名为“main_df”的数据框,其中包含 3 列 X、Y、Z。

X        Y       Z
NaN      NaN     ZVal1
NaN      NaN     ZVal2
XVal1    NaN     NaN
NaN      YVal1   NaN

每一列都携带特定类型(X、Y、Z)的数据,因此如果特定行的 X 列中有数据,则 Y/Z 列中将没有数据,因为它不是 X 类型。

如果将所有 3 列组合在一起,它们会巧妙地“相互滑入”,您将获得一路向下的值。

如何将这 3 列合并为第 4 列,以便忽略 NaN 值,而我们只获取该行的 3 列中存在的任何单个值?

预期输出:

X        Y       Z           XYZ
NaN      NaN     ZVal1       ZVal1
NaN      NaN     ZVal2       ZVal2
XVal1    NaN     NaN         XVal1    
NaN      YVal1   NaN         YVal1   

数据框代码:

 import pandas as pd
 import numpy as np
 df = pd.DataFrame(columns=['X', 'Y', 'Z'], data=[[np.NaN, np.NaN, 'ZVal1'], [np.NaN, np.NaN, 'ZVal2'], ['XVal1', np.NaN, np.NaN], [np.NaN,'YVal1' ,np.NaN]])

现在我正在尝试按照以下方式做一些事情:

df['XYZ'] = df['X'].astype(str) + df['Y'].astype(str) + df['Z'].astype(str) 但这会将 NaN 值组合成一个长字符串

【问题讨论】:

标签: python pandas dataframe


【解决方案1】:

stack:

df["XYZ"] = df.stack().values

得到

>>> df

       X      Y      Z    XYZ
0    NaN    NaN  ZVal1  ZVal1
1    NaN    NaN  ZVal2  ZVal2
2  XVal1    NaN    NaN  XVal1
3    NaN  YVal1    NaN  YVal1

因为你保证每行只有 1 个非 NaN,stack 默认会丢弃 NaN。


另一种花哨的索引方式:

df["XYZ"] = df.to_numpy()[np.arange(len(df)),
                          df.columns.get_indexer(df.notna().idxmax(axis=1))]

对于每一行,查看非 NaN 值的索引并选择它。

【讨论】:

    【解决方案2】:

    试试:

    df["XYZ"] = df.apply(lambda x: x[x.notna()][0], axis=1)
    print(df)
    

    打印:

           X      Y      Z    XYZ
    0    NaN    NaN  ZVal1  ZVal1
    1    NaN    NaN  ZVal2  ZVal2
    2  XVal1    NaN    NaN  XVal1
    3    NaN  YVal1    NaN  YVal1
    

    或者:

    df["XYZ"] = df.bfill(axis=1)["X"]
    print(df)
    

    【讨论】:

    • 先生,我已经发布了第二种方法:)
    • @AnuragDabas 我认为我们在同一波:)
    猜你喜欢
    • 2014-12-02
    • 2021-05-17
    • 2018-02-17
    • 1970-01-01
    • 2022-11-17
    • 2017-06-18
    • 1970-01-01
    • 2016-12-11
    相关资源
    最近更新 更多