6

I have a pandas df where df['value'] is a series of floats.

  • Some of the floats will be whole numbers (like 25.0). I want to create a new column, df['is_it_whole'][i] with values 1 (or True) is the corresponding df['value'][i] is a whole number, 0 or False otherwise.
  • I know I can do a for loop, but I am wondering if there is any trick I can use to do it fast (I have a large df).
  • I tried using df['is_it_whole'] = df['value'].is_integer() but pandas series do not support the is_integer method, I am looking for something similar that would work.

Suggestions?

smci
  • 32,567
  • 20
  • 113
  • 146
user
  • 2,015
  • 6
  • 22
  • 39
  • Your question boils down to "How can I call the Python method `float.is_integer` on a pandas series df['value']?" or in general ***How can I call Python(/numpy/whatever) method type.X on a pandas series `col`?***, to which the general answer is ***`col.apply/map(type.X)`***, and no you generally don't need to declare a lambda (for a 1-arg function X). – smci Apr 21 '19 at 10:16

4 Answers4

7
import pandas as pd
df = pd.DataFrame([['A', 1], ['B', 2.5], ['C', 3.0], ['D', 3.2]], columns=['label', 'value'])
df['is_it_whole'] = df['value'].map(lambda x: x.is_integer())
df

  label  value is_it_whole
0     A    1.0        True
1     B    2.5       False
2     C    3.0        True
3     D    3.2       False
Dennis Golomazov
  • 16,269
  • 5
  • 73
  • 81
  • Wouldn't it be more pandastic to use `apply` here instead of `map`? – lanery Nov 02 '16 at 00:39
  • @lanery As pointed out [here](http://stackoverflow.com/a/19798528/304209), `apply` "works on a row / column basis of a DataFrame", while `map` works element-wise on a Series (note the examples there). I personally find it more intuitive to use `map` for a column, but YMMV. – Dennis Golomazov Nov 02 '16 at 00:54
  • 1
    You don't need to declare a lambda function. Just directly do `df['value'].map(float.is_integer)` – smci Apr 21 '19 at 10:10
3

You can try:

df['is_it_whole'] = (df['value'].round() == df['value'])

Or to take into account float number inaccuracy:

tol = 0.001
df['is_it_whole'] = ((df['value'].round() - df['value']).abs() < tol)
Psidom
  • 209,562
  • 33
  • 339
  • 356
1

You don't need to declare a lambda function. Just directly apply df['value'].map(float.is_integer)

import pandas as pd
df = pd.DataFrame([['A', 1], ['B', 2.5], ['C', 3.0], ['D', 3.2]], columns=['label', 'value'])
df['is_it_whole'] = df['value'].map(float.is_integer)

>>> df
  label  value  is_it_whole
0     A    1.0         True
1     B    2.5        False
2     C    3.0         True
3     D    3.2        False
smci
  • 32,567
  • 20
  • 113
  • 146
0

This applies is_integer to each element in the series:

df['is_it_whole'] = df['value'].apply(lambda x: x.is_integer())
simon
  • 2,561
  • 16
  • 26
  • You don't need to declare a lambda function. Just directly do `df['value'].map(float.is_integer)` – smci Apr 21 '19 at 10:10