title: SettingWithCopyWarning using pandas apply
body: <p>Trying to figure out why the below function is returning the dreaded <code>SettingWithCopyWarning</code>...
  Here is my function that intends to modify the dataframe <code>df</code> by reference.</p>
  
  <pre><code>def remove_outliers_by_group(df, cols):
      """
      Removes outliers based on median and median deviation computed using cols
      :param df: The dataframe reference
      :param cols: The columns to compute the median and median dev of
      :return:
      """
      flattened = df[cols].as_matrix().reshape(-1, )
      median = np.nanmedian(flattened)
      median_dev = np.nanmedian(np.abs(flattened) - median)
      for col in cols:
          df[col] = df[col].apply(lambda x: np.nan if get_absolute_median_z_score(x, median, median_dev) &gt;= 2 else x)
  </code></pre>
  
  <p>And the offending line is <code>df[col] = df[col].apply(lambda x: np.nan if get_absolute_median_z_score(x, median, median_dev) &gt;= 2 else x)</code> as per this error:</p>
  
  <blockquote>
    <p>A value is trying to be set on a copy of a slice from a DataFrame. Try
    using .loc[row_indexer,col_indexer] = value instead</p>
    
    <p>See the caveats in the documentation:
    <a href="http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy" rel="noreferrer">http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy</a>
    df[col] = df[col].apply(lambda x: np.nan if
    get_absolute_median_z_score(x, median, median_dev) >= 2 else x)</p>
  </blockquote>
  
  <p>What I don't understand is that I see this pattern all over the place, using something like <code>df['a'] = df['a'].apply(lambda x: ...)</code>, so I can't imagine <em>all</em> of them are doing it wrong. </p>
  
  <p>Am I doing it wrong? What is the best way to do this? I want to modify the <em>original</em> dataframe. </p>
  
  <p>Thanks for your help.</p>