Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find the line that is generating a Pandas SettingWithCopyWarning?

I have a large block of code that is, at some point somewhere, generating a setting with copy warning in pandas (this problem).

I know how to fix the problem, but I can't find what line number it is! Is there a way to back out the line number (apart from brute force methods like debug-stepping or putting in multiple prints)? The only output I get is the below, which doesn't go up the stack to my code:

C:\Anaconda3\lib\site-packages\pandas\core\frame.py:2302: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame  **kwargs) 
like image 856
tim654321 Avatar asked May 22 '15 08:05

tim654321


People also ask

How do I stop Pandas warnings SettingWithCopyWarning?

One approach that can be used to suppress SettingWithCopyWarning is to perform the chained operations into just a single loc operation. This will ensure that the assignment happens on the original DataFrame instead of a copy. Therefore, if we attempt doing so the warning should no longer be raised.

How do I get rid of SettingWithCopyWarning?

To make it clear you only want to assign a copy of the data (versus a view of the original slice) you can append . copy() to your request, e.g.

What is setting with copy warning?

Warnings should never be ignored. If you have ever done data analysis or manipulation with Pandas, it is highly likely that you encounter the SettingWithCopy warning at least once. This warning occurs when we try to do an assignment using chained indexing because chained indexing has inherently unpredictable results.


1 Answers

Set pd.options.mode.chained_assignment = 'raise'

This will throw an exception pointing to the line which triggers SettingWithCopyError.

UPDATE: how to catch the error, and interrogate the stacktrace to get the actual offending lineno:

import pandas as pd from inspect import currentframe, getframeinfo from pandas.core.common import SettingWithCopyError  pd.options.mode.chained_assignment = 'raise'  df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})  df2 = df[df['a'] == 2]  try:     df2['b'] = 'foo' except SettingWithCopyError:     print('handling..')     frameinfo = getframeinfo(currentframe())     print(frameinfo.lineno) 
like image 188
Julius Avatar answered Oct 04 '22 09:10

Julius