Reputation: 3166
I am trying to compare values in a table, it so happens that some might be zero and I therefore get an error message that I cannot divide by 0. Why isn't the script returning inf instead of an error? When I test this script on a dataframe with one column it works, with more than one column it breaks with the Zero Division Error.
table[change] = ['{0}%'.format(str(round(100*x,2)) for x in \
(table.ix[:,table.shape[1]-1] - table.ix[:,0]) / table.ix[:,0]]
table example:
0 1 2 3 4 5 6 \
numbers 0.0 100.0 120.0 220.0 250.0 300.0 500.0\\
revenues 50.0 100.0 120.0 220.0 250.0 300.0 500.0
where table.ix[:,0]
is 0.0.
Some of the values at table.ix[:,0]
are zero and others are not, hence, try and except in my experience will not work because the script will break once the value divisible is equal to 0.
I tried two of the other methods and they did not work for me.
Can you be a little more descriptive in your answer? I am struggling to take the approach given.
I have another approach which I am trying and it is not working. Do not see yet what the problem is:
for index, row in table.iterrows():
if row[0] == 0:
table[change] = 'Nan'
else:
x = (row[-1] - row[0]) / row[0]
table[change] = '{0} {1}%'.format( str(round(100 * x, 2)))
The 'change' column contains the same values (i.e. the last comparison of the table)
Upvotes: 0
Views: 960
Reputation: 1082
Looks like python has a specific ZeroDivisionError
, you should use try except
to do something else in that case.
try:
table[change] = ['{0}%'.format(str(round(100*x,2)) for x in \
(table.ix[:,table.shape[1]-1] - table.ix[:,0]) / table.ix[:,0]]
except ZeroDivisionError:
table[change] = inf
In that case, you can just divide the whole Series, and Pandas will do the inf substitution for you. Something like:
if df1.ndim == 1:
table[change] = inf
elif df1.ndim > 1 and df1.shape[0] > 1:
table[change] = ['{0}%'.format(str(round(100*x,2)) for x in \
(table.ix[:,table.shape[1]-1] - table.ix[:,0]) / table.ix[:,0]]
The fact that your original example only had one row seems to make Pandas fetch the value in that cell for the division. If you do the division with an array with more than one row, it has the behaviour that I think you were originally expecting.
EDIT:
I've just spotted the generator expression that I completely overlooked. This is much easier than I thought. Performing your normalisation then, if your version of pandas is up to date, then you can call round if you want.
table["change"] = 100 * ((table.iloc[:, -1] - table.iloc[:, 0])/ table.iloc[:, 0])
#And if you're running Pandas v 0.17.0
table.round({"change" : 2})
Upvotes: 1
Reputation: 33335
Dividing by zero is usually a serious error; defaulting to infinity would not be appropriate for most situations.
Before attempting to calculate the value, check if the divisor (table.ix[:,0]
in this case) is equal to zero. If it is, then skip the calculation and just assign whatever value you want.
Or you can wrap the division calculation in a try/except block as suggested by @Andrew.
Upvotes: 1