Q:

Apply a lambda function to a dataframe with NaN values?

I am trying to perform calculations that change between rows with variables that remain consistent. How can I use this lambda function when a row has incomplete data? 
Follow up to this question: Create a new column based on calculations that change between rows?
#example
import pandas as pd
import numpy as np

conversion = [["a",5],["b",1],["c",10]]
conversion_table = pd.DataFrame(conversion,columns=['Variable','Cost'])

data1 = [[1,"2*a+b"],[2,"c"],[3,"2*c"],[4, np.NaN]]
to_solve = pd.DataFrame(data1,columns=['Day','Q1'])

#Desired dataframe: 

desired = [[1,11],[2,10],[3,20]]
desired_table=pd.DataFrame(desired,columns=['Day','desired output'])

#Using lambda to map values does not work when NaN is present.

#Map values
mapping = dict(zip(conversion_table['Variable'], conversion_table['Cost']))

desired_table["solved"]=to_solve['Q1'].map(lambda x: eval(''.join([str(mapping[i]) if i.isalpha() else str(i) for i in x])))

This code works when my columns do not contain NaN values, but I need this to work when I have incomplete data.
I receive the following error: 'float' object is not iterable. 
I just want to leave the NaN values where they are and fill in the rest. 

A:

You have to add an optional parameter na_action='ignore' to the .map method which propagate NaN values, without passing them to the mapping correspondence
Use:
def solve(x):
    expr = ''.join(str(mapping[k]) if k in mapping else str(k) for k in x)
    return pd.eval(expr)

desired_table["solved"]= to_solve['Q1'].map(solve, na_action='ignore')

This results the desired_table as:
   Day  desired output  solved
0    1              11    11.0
1    2              10    10.0
2    3              20    20.0

