Concatenate two columns in pandas with NaN
Asked Answered
T

3

10

I have a dataframe like this

df = (pd.DataFrame({'ID': ['ID1', 'ID2', 'ID3'], 
                        'colA': ['A', 'B', 'C'], 
                        'colB': ['D', np.nan, 'E']}))

df

    ID  colA   colB
0   ID1 A      D
1   ID2 B      NaN
2   ID3 C      E

I want to combine the two columns, however keep only column A if column B is NaN. Hence Expected output is

    ID  colA    colB    colC
0   ID1 A       D       A_D
1   ID2 B       NaN     B
2   ID3 C       E       C_E
Tyrannicide answered 19/7, 2019 at 12:17 Comment(0)
E
11

Idea is add _ to second column with _, so after replace missing value by empty string is not added _ for missing values:

df['colC'] = df['colA'] + ('_' + df['colB']).fillna('')
print (df)
    ID colA colB colC
0  ID1    A    D  A_D
1  ID2    B  NaN    B
2  ID3    C    E  C_E

If not sure where are missing values (in colA or colB):

df['colC'] = (df['colA'].fillna('') + '_' + df['colB'].fillna('')).str.strip('_')

Also is possible test each column separately:

m1 = df['colA'].isna()
m2 = df['colB'].isna()

df['colC'] = np.select([m1, m2, m1 & m2], 
                        [df['colB'], df['colA'], np.nan], 
                        default=df['colA'] + '_' + df['colB'])
print (df)

    ID colA colB colC
0  ID1    A    D  A_D
1  ID2    B  NaN    B
2  ID3  NaN    E    E
3  ID4  NaN  NaN  NaN
Euphemia answered 19/7, 2019 at 12:21 Comment(0)
M
7

Learned this from Datanovice's answer:

df['col_c'] = df[['colA', 'colB']].stack().groupby(level=0).agg('_'.join)
df

    ID  colA    colB    col_c
0   ID1 A       D       A_D
1   ID2 B       NaN     B
2   ID3 C       E       C_E
Merrygoround answered 1/7, 2020 at 16:58 Comment(0)
A
3

Using Series.str.cat() accessor.

  • sep='_' - Separator to be put between the two strings.
  • na_rep='' - To ignore NaN value, it's None or string value to replace in place of null values.
  • str.replace('_$', '')- To remove underscore at the end.

Ex.

import pandas as pd
import numpy as np

df = (pd.DataFrame({'ID': ['ID1', 'ID2', 'ID3'],
                        'colA': ['A', 'B', 'C'],
                        'colB': ['D', np.nan, 'E']}))


df['colC']= df.colA.str.cat(df.colB,sep="_",na_rep='').str.replace('_$', '')
print(df)

O/P:

    ID colA colB colC
0  ID1    A    D  A_D
1  ID2    B  NaN    B
2  ID3    C    E  C_E
Alienation answered 19/7, 2019 at 13:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.