2

I have a dataframe df and gives value error when apply a function on it.

df = pd.DataFrame({
    'ID': range(1, 4),
    'col1': [10, 5, 10],
    'col2': [15, 10, 15],
    'col3': [10, 15, 15],
    'total': [35, 30, 40]
})

print(df)

     ID  col1 col2 col3 total
0     1    10   15   10    35
1     2    5    10   15    30
2     3    10   15   15    40


def round_up(value):
    remainder = value % 5
    if remainder == 0:
        new_val = value
    if remainder == 1:
        new_val = value - 1
    if remainder == 2:
        new_val = value - 2
    if remainder == 3:
        new_val = value + 2
    if remainder == 4:
        new_val = value + 1

    return new_val

df.iloc[:, 1:-1] = df.iloc[:, 1:-1].apply(round_up)

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

prashant
  • 231
  • 1
  • 3
  • 8
  • Does this answer your question? [Error: The truth value of a Series is ambiguous - Python pandas](https://stackoverflow.com/questions/45493948/error-the-truth-value-of-a-series-is-ambiguous-python-pandas) – tomjn Jun 16 '21 at 11:55
  • Try with [applymap](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.applymap.html#pandas-dataframe-applymap) instead of `apply`. Currently you're trying to apply those operations to entire columns which means `remainder = value % 5` produces a `Series` of values in (explained more in the proposed duplicate). `applymap` will apply the function to each _cell_. – Henry Ecker Jun 16 '21 at 11:55

1 Answers1

2

As you are applying across several columns, you need to use applymap instead of apply. Furthermore, your function to round can be simplified as well, see below

df = pd.DataFrame({
    'ID': range(1, 4),
    'col1': [10, 5, 10],
    'col2': [15, 10, 15],
    'col3': [10, 15, 15],
    'total': [35, 30, 40]
})

def round_up(value):
    return (value + 2) // 5 * 5)

df.iloc[:, 1:-1] = df.iloc[:, 1:-1].applymap(round_up)
oskros
  • 3,101
  • 2
  • 9
  • 28