title: Can I split this column containing a mix of tuples/None more efficiently?
body: <p>I have a simple DataFrame:</p>
  
  <pre><code>import pandas as pd
  df = pd.DataFrame({'id':list('abcd')})
  df['tuples'] = df.index.map(lambda i:(i,i+1))
  
  # outputs:
  #   id  tuples
  # 0  a  (0, 1)
  # 1  b  (1, 2)
  # 2  c  (2, 3)
  # 3  d  (3, 4)
  </code></pre>
  
  <p>I can then split the tuples column into two very simply, e.g.</p>
  
  <pre><code>df[['x','y']] = pd.DataFrame(df.tuples.tolist())
  
  # outputs:
  #   id  tuples  x  y
  # 0  a  (0, 1)  0  1
  # 1  b  (1, 2)  1  2
  # 2  c  (2, 3)  2  3
  # 3  d  (3, 4)  3  4
  </code></pre>
  
  <p>This approach also works:</p>
  
  <pre><code>df[['x','y']] = df.apply(lambda x:x.tuples,result_type='expand',axis=1)
  </code></pre>
  
  <p>However if my DataFrame is slightly more complex, e.g.</p>
  
  <pre><code>df = pd.DataFrame({'id':list('abcd')})
  df['tuples'] = df.index.map(lambda i:(i,i+1) if i%2 else None)
  
  # outputs:
  #   id  tuples
  # 0  a    None
  # 1  b  (1, 2)
  # 2  c    None
  # 3  d  (3, 4)
  </code></pre>
  
  <p>then the first approach throws "Columns must be same length as key" (of course) because some rows have two values and some have none, and my code anticipates two.</p>
  
  <p>I can use .loc to create single columns, twice.</p>
  
  <pre><code>get_rows = df.tuples.notnull() # return rows with tuples
  
  df.loc[get_rows,'x'] = df.tuples.str[0]
  df.loc[get_rows,'y'] = df.tuples.str[1]
  
  # outputs:
  #   id  tuples    x    y
  # 0  a    None  NaN  NaN
  # 1  b  (1, 2)  1.0  2.0
  # 2  c    None  NaN  NaN
  # 3  d  (3, 4)  3.0  4.0
  </code></pre>
  
  <p>[Aside: useful how the indexing carries assigns only relevant rows from the right, without having to specify them.]</p>
  
  <p>However, I can't use .loc to create two columns at once, e.g.</p>
  
  <pre><code># This isn't valid use of .loc
  df.loc[get_rows,['x','y']] = df.loc[get_rows,'tuples'].map(lambda x:list(x))
  </code></pre>
  
  <p>as it throws the error "shape mismatch: value array of shape (2,2) could not be broadcast to indexing result of shape (2,)".</p>
  
  <p>I also can't use this</p>
  
  <pre><code>df[get_rows][['x','y']] = df[get_rows].apply(lambda x:x.tuples,result_type='expand',axis=1)
  </code></pre>
  
  <p>as it throws the usual "A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc..."</p>
  
  <p>I can't help thinking I'm missing something.</p>