title: Pandas Apply lambda function null values
body: <p>I'm trying to split a column in two, but I know there are null values in my data.  Imagine this dataframe:</p>
  
  <pre><code>df = pd.DataFrame(['fruit: apple','vegetable: asparagus',None, 'fruit: pear'], columns = ['text'])
  
  df
  
                     text
  0          fruit: apple
  1  vegetable: asparagus
  2                   None
  3           fruit: pear
  </code></pre>
  
  <p>I'd like to split this into multiple columns like so:</p>
  
  <pre><code>df['cat'] = df['text'].apply(lambda x: 'unknown' if x == None else x.split(': ')[0])
  df['value'] = df['text'].apply(lambda x: 'unknown' if x == None else x.split(': ')[1])
  
  print df
  
                     text        cat      value
  0          fruit: apple      fruit      apple
  1  vegetable: asparagus  vegetable  asparagus
  2                  None    unknown    unknown
  3           fruit: pear      fruit       pear
  </code></pre>
  
  <p>However, if I have the following df instead:</p>
  
  <pre><code>df = pd.DataFrame(['fruit: apple','vegetable: asparagus',np.nan, 'fruit: pear'], columns = ['text'])
  </code></pre>
  
  <p>splitting results in the following error:</p>
  
  <pre><code>df['cat'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[0])
  
  ---------------------------------------------------------------------------
  AttributeError                            Traceback (most recent call last)
  &lt;ipython-input-159-8e5bca809635&gt; in &lt;module&gt;()
        1 df = pd.DataFrame(['fruit: apple','vegetable: asparagus',np.nan, 'fruit: pear'], columns = ['text'])
        2 #df.columns = ['col_name']
  ----&gt; 3 df['cat'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[0])
        4 df['value'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[1])
  
  C:\Python27\lib\site-packages\pandas\core\series.pyc in apply(self, func, convert_dtype, args, **kwds)
     2158             values = lib.map_infer(values, lib.Timestamp)
     2159 
  -&gt; 2160         mapped = lib.map_infer(values, f, convert=convert_dtype)
     2161         if len(mapped) and isinstance(mapped[0], Series):
     2162             from pandas.core.frame import DataFrame
  
  pandas\src\inference.pyx in pandas.lib.map_infer (pandas\lib.c:62187)()
  
  &lt;ipython-input-159-8e5bca809635&gt; in &lt;lambda&gt;(x)
        1 df = pd.DataFrame(['fruit: apple','vegetable: asparagus',np.nan, 'fruit: pear'], columns = ['text'])
        2 #df.columns = ['col_name']
  ----&gt; 3 df['cat'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[0])
        4 df['value'] = df['text'].apply(lambda x: 'unknown' if x == np.nan else x.split(': ')[1])
  
  AttributeError: 'float' object has no attribute 'split'
  </code></pre>
  
  <p><strong>How do I do the same split with NaN values?</strong>
  Is there generally a better way to apply a split function that ignores null values?  </p>
  
  <p>Imagine this wasn't a string example, instead if I had the following:</p>
  
  <pre><code>df = pd.DataFrame([2,4,6,8,10,np.nan,12], columns = ['numerics'])
  df['numerics'].apply(lambda x: np.nan if pd.isnull(x) else x/2.0)
  </code></pre>
  
  <p>I feel like Series.apply should almost take an argument that instructs it to skip null rows and just output them as nulls. I haven't found a better <em>generic</em> way to do transformations to a series without having to manually avoid nulls. </p>