title: Unpredictable pandas slice assignment behavior with no SettingWithCopyWarning
body: <p>It's <a href="https://stackoverflow.com/questions/20625582/how-to-deal-with-settingwithcopywarning-in-pandas">well known</a> (and <a href="http://pandas-docs.github.io/pandas-docs-travis/indexing.html#indexing-view-versus-copy" rel="nofollow noreferrer">understandable</a>) that pandas behavior is essentially unpredictable when assigning to a slice. But I'm used to being warned about it by <code>SettingWithCopy</code> warning.</p>
  
  <p>Why is the warning not generated in either of the following two code snippets, and what techniques could reduce the chance of writing such code unintentionally?</p>
  
  <pre><code># pandas 0.18.1, python 3.5.1
  import pandas as pd
  data = pd.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c']})
  new_data = data[['a', 'b']]
  data = data['a']
  new_data.loc[0, 'a'] = 100 # no warning, doesn't propagate to data
  
  data[0] == 1
  True
  
  
  data = pd.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c']})
  new_data = data['a']
  data = data['a']
  new_data.loc[0] = 100 # no warning, propagates to data
  
  data[0] == 100
  True
  </code></pre>
  
  <p>I thought the explanation was that pandas only produces the warning when the parent DataFrame is still reachable from the current context. (This would be a weakness of the detection algorithm, as my previous examples show.)</p>
  
  <p>In the next snippet, AFAIK the original two-column DataFrame is no longer reachable, and yet pandas warning mechanism manages to trigger (luckily):</p>
  
  <pre><code>data = pd.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c']})
  new_data = data['a']
  data = data[['a']]
  new_data.loc[0] = 100 # warning, so we're safe
  </code></pre>
  
  <p>Edit:</p>
  
  <p>While investigating this, I found another case of a missing warning:</p>
  
  <pre><code>data = pd.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c']})
  data = data.groupby('a')
  new_data = data.filter(lambda g: len(g)==1)
  new_data.loc[0, 'a'] = 100 # no warning, does not propagate to data
  assert data.filter(lambda g: True).loc[0, 'a'] == 1
  </code></pre>
  
  <p>Even though an almost identical example does trigger a warning:</p>
  
  <pre><code>data = pd.DataFrame({'a': [1, 2, 2], 'b': ['a', 'b', 'c']})
  data = data.groupby('a')
  new_data = data.filter(lambda g: len(g)==1)
  new_data.loc[0, 'a'] = 100 # warning, does not propagate to data
  assert data.filter(lambda g: True).loc[0, 'a'] == 1
  </code></pre>
  
  <p>Update: I'm responding to the answer by @firelynx here because it's hard to put it in the comment.</p>
  
  <p>In the answer, @firelynx says that the first code snippet results in no warning because I'm taking the entire dataframe. But even if I took part of it, I still don't get a warning:</p>
  
  <pre><code># pandas 0.18.1, python 3.5.1
  import pandas as pd
  data = pd.DataFrame({'a': [1, 2, 3], 'b': ['a', 'b', 'c'], c: range(3)})
  new_data = data[['a', 'b']]
  data = data['a']
  new_data.loc[0, 'a'] = 100 # no warning, doesn't propagate to data
  
  data[0] == 1
  True
  </code></pre>