I have a dataframe as below:
A B
0 Morning NaN
1 24 afternoon
2 34 23
3 23 16
4 NaN 13
5 NaN NaN
6 15.5 1
I want to have a new column 'sumA' which will 2 for these cells (except string and NAN) , so i wrote the code below:
df['sumA'] = df['A'].apply(lambda x: x 2 if (df['A'].notnull) and (type(df['A'])== int) else x )
i got the result below , it doesn't 2 to these cells which i expected. Could you please help assist on this?
A B sumA
0 Morning NaN Morning
1 24 afternoon 24
2 34 23 34
3 23 16 23
4 NaN 13 NaN
5 NaN NaN NaN
6 15.5 1 15.5
CodePudding user response:
You can convert values to numeric with errors='coerce'
for NaN
s if not numbers and then add 2
, last if need non numeric values use fillna
:
df['sumA'] = pd.to_numeric(df['A'], errors='coerce').add(2).fillna(df['A'])
print (df)
A B sumA
0 Morning NaN Morning
1 24 afternoon 26.0
2 34 23 36.0
3 23 16 25.0
4 NaN 13 NaN
5 NaN NaN NaN
6 15.5 1 17.5
Better if only numeric columns finally - numbers or missing values:
df['sumA'] = pd.to_numeric(df['A'], errors='coerce').add(2)
print (df)
A B sumA
0 Morning NaN NaN
1 24 afternoon 26.0
2 34 23 36.0
3 23 16 25.0
4 NaN 13 NaN
5 NaN NaN NaN
6 15.5 1 17.5
If need custom function:
#convert to numeric - if strings convert to NaNs
df['A'] = pd.to_numeric(df['A'], errors='coerce')
#pass custom function
df['sumA'] = df['A'].apply(lambda x: x 2 if pd.notna(x) else x )
print (df)
A B sumA
0 NaN NaN NaN
1 24.0 afternoon 26.0
2 34.0 23 36.0
3 23.0 16 25.0
4 NaN 13 NaN
5 NaN NaN NaN
6 15.5 1 17.5
If really need mixing numeric and non numeric:
#convert strings numbers to numbers (float, int)
df['A'] = pd.to_numeric(df['A'], errors='coerce').fillna(df['A'])
#apply function
df['sumA'] = df['A'].apply(lambda x: x 2 if pd.notna(x) and not isinstance(x, str) else x)
print (df)
A B sumA
0 Morning NaN Morning
1 24.0 afternoon 26.0
2 34.0 23 36.0
3 23.0 16 25.0
4 NaN 13 NaN
5 NaN NaN NaN
6 15.5 1 17.5