1

I have tried several versions but all of them throw a warning, starting with:

colName = 'age'    
df_plot[colName][df_plot[colName]>10] = 10
 SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame. See the caveats in the documentation:

http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

Based on the link from the warning then:

df_plot.loc[:, (colName, df_plot[colName]>10)] = 10
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

Next

df_plot.loc[colName, df_plot[colName] > 10] = 10
TypeError: 'Series' objects are mutable, thus they cannot be hashed

And finally based on a stack-overflow answer also:

df_plot[colName] = df_plot[colName].apply(lambda x: [y if y <= 10 else 10 for y in x])


TypeError: 'float' object is not iterable

What am I doing wrong here?

3
  • 2
    df_plot.loc[df_plot[colName]>10, colName] = 10 ? Commented Oct 29, 2019 at 9:09
  • First option doesn't even throw any warnings for me. Commented Oct 29, 2019 at 9:12
  • Concerning the last option: if you drop the list comprehension, it should work fine, i.e.: df_plot[colName] = df_plot[colName].apply(lambda x: x if x <= 10 else 10) Commented Oct 29, 2019 at 9:56

3 Answers 3

2

There's an easier way to clip values:

df_plot[colName] = df_plot[colName].clip(upper=10)
Sign up to request clarification or add additional context in comments.

Comments

1

Your first attempt seems correct to me, and works without warnings on my machine.

df = pd.DataFrame({'age':range(5,15), 'size':range(10)})
colName = 'age'
df[colName][df[colName]>10] = 10
print(df)

Output:

   age  size
0    5     0
1    6     1
2    7     2
3    8     3
4    9     4
5   10     5
6   10     6
7   10     7
8   10     8
9   10     9

4 Comments

Interesting, your minimal version works on my system without warning but why does it throw a warning with my "real" data frame ...? EDIT: My column is of type <class 'pandas.core.series.Series'> - very strange (it's an import from a SQL DB)
@lordy: The warning occurs only in case df_plot is already a copy of a slice. This depends on how df_plot is defined. Maybe, before your posted commands, you slice another DataFrame for example by using some command like this: df_plot = df_original[['age', 'height', 'weight']]. Then the warning is raise. If instead you do df_plot = df_original[['age', 'height', 'weight']].copy() the warning will disappear.
@brexi: you are right - I am doing that as I select only a subset of columns for plotting but the .copy() does not remove the warning ...
that is bizarre. Could you maybe post a few more lines of code leading up to what you already posted?
0

Have you tried numpy.where()? Let me use @Zvika's sample df.

>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame({'age':range(5,15), 'size':range(10)})
>>> df
   age  size
0    5     0
1    6     1
2    7     2
3    8     3
4    9     4
5   10     5
6   11     6
7   12     7
8   13     8
9   14     9

>>> df['age'] = np.where(df['age']>10, [10],df['age'])
>>> df
   age  size
0    5     0
1    6     1
2    7     2
3    8     3
4    9     4
5   10     5
6   10     6
7   10     7
8   10     8
9   10     9

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.