16

I would like to slice a DataFrame with a Boolean index obtaining a copy, and then do stuff on that copy independently of the original DataFrame.

Judging from this answer, selecting with .loc using a Boolean array will hand me back a copy, but then, if I try to change the copy, SettingWithCopyWarning gets in the way. Would this then be the correct way:

import numpy as np
import pandas as pd
d1 = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e'])
# create a new dataframe from the sliced copy
d2 = pd.DataFrame(d1.loc[d1.a > 1, :])
# do stuff with d2, keep d1 unchanged
Pietro Marchesi
  • 852
  • 2
  • 8
  • 18
  • `SettingWithCopyWarning` is just a warning. It tells you that modifications you do on that DataFrame will not change the original DataFrame. You can disable them altogether or just use `d2.is_copy = None` after the assignment. – ayhan Jul 07 '17 at 11:10
  • DataFrame.is_copy is no longer in the API. – Rich Andrews Feb 23 '21 at 20:39

1 Answers1

23

You need copy with boolean indexing, new DataFrame constructor is not necessary:

d2 = d1[d1.a > 1].copy()

Explanation of warning:

If you modify values in d2 later you will find that the modifications do not propagate back to the original data (d1), and that Pandas does warning.

jezrael
  • 822,522
  • 95
  • 1,334
  • 1,252
  • That's what I was using, I changed it because I seem to have read in the docs somewhere that `.copy()` is not the recommended way, but I may have been mistaken. – Pietro Marchesi Jul 07 '17 at 09:19
  • Yes, if need new object need copy. if not need original `d1 = d1[d1.a > 1]` should work also. – jezrael Jul 07 '17 at 09:20