合并(连接)具有缺失值和不同类型(str 和 int)的 pandas 列

bek*_*fen 5 python concatenation nan dataframe pandas

我有一个数据框,其中有一列包含整数,我想将其与一列包含字符串值的组合。两列都是对象数据类型。问题是这些列也可能是 NaN。

我找到的解决方案会导致不同的错误或不良结果。

我的数据框如下所示:

指数 剂量持续时间单位 剂量数量值 剂量单位 数量值
0
1 片剂
2 2
3 1 片剂
4 2 片剂

创建数据框的代码:

df = pd.DataFrame([["day",None,None,None],["day",None,"tablet(s)",None],["day",2,"tablet(s)",None],["day",1,"tablet(s)",None],["day",2,"tablet(s)",None]], columns=["dosagedurationunit","dosagequantityvalue","dosagequantityunit","quantityvalue"])
Run Code Online (Sandbox Code Playgroud)

以下答案适用于相同类型(str)的列: Combine pandas string columns with Missing Values

  • 在串联之前将列转换为 str 数据类型会产生“nan”字符串,例如“NaN Tablet(s)”。
  • 当要“连接”的列之一中有整数时,使用以下代码会导致类型错误。
df['DOSE'] = df[['dosagequantityvalue', 'dosagequantityunit']].apply(
            lambda x: None if x.isnull().all() else ' '.join(x.dropna()), axis=1)
Run Code Online (Sandbox Code Playgroud)
  • 类型错误:序列项 0:预期的 str 实例,找到 int

所需的输出数据帧:

指数 剂量持续时间单位 剂量数量值 剂量单位 数量值 标准化剂量
0
1 片剂 片剂
2 2 2
3 1 片剂 1 片
4 2 片剂 2 片

实际上,NaN 或“片剂”的 NORAMLIZED_DOSE 提供零信息。我可以删除所有剂量量值为 NaN 的行,但我不知道这是否适用于生产/非样本数据集。此外,我还需要一个函数来优雅地处理这个操作。

在处理一列或两列中可能存在整数和 NaN 值的情况时,如何将两列(剂量量值和剂量量单位)连接成一个新列(NORMALIZED_DOSE)?

tdy*_*tdy 3

更新

\n

如果我把我的答案放在一个函数中replace_concat_replace()

\n
def replace_concat_replace(df):\n    df = df.replace(np.nan, \'\').astype(str)\n    s = df.dosagequantityvalue + \' \' + df.dosagequantityunit\n    s = s.str.strip().replace(\'\', np.nan)\n    return s\n
Run Code Online (Sandbox Code Playgroud)\n

那么它的%timeit速度大约是 2.5 倍concat_df_cols_new()

\n
>>> %timeit df[\'NORMALIZED_DOSAGE\'] = replace_concat_replace(df[[\'dosagequantityvalue\', \'dosagequantityunit\']])\n41.7 ms \xc2\xb1 2.21 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n\n>>> %timeit df[\'NORMALIZED_DOSAGE\'] = concat_df_cols_new(df[[\'dosagequantityvalue\', \'dosagequantityunit\']])\n105 ms \xc2\xb1 15.7 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n

然而,concat_df_cols_new()可以处理任意列。

\n
\n

原答案

\n

您可以在连接之前使用replace()每个nan空字符串\'\',然后replace()在连接之后将它们返回。

\n

请注意,我用nan的是None匹配您的表格。

\n
>>> %timeit df[\'NORMALIZED_DOSAGE\'] = replace_concat_replace(df[[\'dosagequantityvalue\', \'dosagequantityunit\']])\n41.7 ms \xc2\xb1 2.21 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n\n>>> %timeit df[\'NORMALIZED_DOSAGE\'] = concat_df_cols_new(df[[\'dosagequantityvalue\', \'dosagequantityunit\']])\n105 ms \xc2\xb1 15.7 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n

输出:

\n
  dosagedurationunit dosagequantityvalue dosagequantityunit quantityvalue NORMALIZED_DOSAGE\n0                day                 NaN                NaN           NaN               NaN\n1                day                 NaN          tablet(s)           NaN         tablet(s)\n2                day                 2.0                NaN           NaN               2.0\n3                day                 1.0          tablet(s)           NaN     1.0 tablet(s)\n4                day                 2.0          tablet(s)           NaN     2.0 tablet(s)\n
Run Code Online (Sandbox Code Playgroud)\n