web-dev-qa-db-fra.com

Comment gérer la "division par zéro" avec les cadres de données des pandas lors de la manipulation des colonnes?

Je travaille avec des centaines de bases de données de pandas. Une base de données typique est la suivante:

import pandas as pd
import numpy as np
data = 'filename.csv'
df = pd.DataFrame(data)
df 

        one       two     three  four   five
a  0.469112 -0.282863 -1.509059  bar   True
b  0.932424  1.224234  7.823421  bar  False
c -1.135632  1.212112 -0.173215  bar  False
d  0.232424  2.342112  0.982342  unbar True
e  0.119209 -1.044236 -0.861849  bar   True
f -2.104569 -0.494929  1.071804  bar  False
....

Il existe certaines opérations dans lesquelles je divise des valeurs de colonnes, par exemple. 

df['one']/df['two'] 

Cependant, il y a des moments où je divise par zéro, ou peut-être les deux 

df['one'] = 0
df['two'] = 0

Naturellement, cela génère l'erreur: 

ZeroDivisionError: division by zero

Je préférerais que 0/0 signifie réellement "il n'y a rien ici", car c'est souvent ce que signifie un tel zéro dans un cadre de données.

(a) Comment pourrais-je coder cela pour signifier que "diviser par zéro" vaut 0?

(b) Comment pourrais-je coder ceci pour "passer" si une division par zéro est rencontrée? 

6
ShanZhengYang

Deux approches à considérer:

Préparez vos données de manière à ne jamais diviser par zéro, en codant explicitement une valeur "pas de données" et en le testant.

Entourez chaque division qui pourrait entraîner une erreur avec une paire try/except, comme décrit à https://wiki.python.org/moin/HandlingExceptions (avec un exemple de division par zéro à utiliser)

(x,y) = (5,0)
try:
  z = x/y
except ZeroDivisionError:
  print "divide by zero"

Je m'inquiète de la situation où vos données incluent un zéro qui est vraiment un zéro (et non une valeur manquante).

4
vielmetti

Il serait probablement plus utile d’utiliser une structure de données dont le dénominateur est zéro (voir la dernière ligne de la colonne two).

        one       two     three   four   five
a  0.469112 -0.282863 -1.509059    bar   True
b  0.932424  1.224234  7.823421    bar  False
c -1.135632  1.212112 -0.173215    bar  False
d  0.232424  2.342112  0.982342  unbar   True
e  0.119209 -1.044236 -0.861849    bar   True
f -2.104569  0.000000  1.071804    bar  False

>>> df.one / df.two
a   -1.658442
b    0.761639
c   -0.936904
d    0.099237
e   -0.114159
f        -inf  # <<< Note division by zero
dtype: float64

Lorsque l'une des valeurs est zéro, vous devriez obtenir inf ou -inf dans le résultat. Une façon de convertir ces valeurs est la suivante:

df['result'] = df.one.div(df.two)

df.loc[~np.isfinite(df['result']), 'result'] = np.nan  # Or = 0 per part a) of question.
# or df.loc[np.isinf(df['result']), ...

>>> df
        one       two     three   four   five    result
a  0.469112 -0.282863 -1.509059    bar   True -1.658442
b  0.932424  1.224234  7.823421    bar  False  0.761639
c -1.135632  1.212112 -0.173215    bar  False -0.936904
d  0.232424  2.342112  0.982342  unbar   True  0.099237
e  0.119209 -1.044236 -0.861849    bar   True -0.114159
f -2.104569  0.000000  1.071804    bar  False       NaN
13
Alexander

Vous pouvez toujours utiliser une instruction try:

try:
  z = var1/var2
except ZeroDivisionError:
  print ("0") #As python-3's rule is: Parentheses

OU...

Vous pouvez aussi faire:

if var1==0:
    if var2==0:
        print("0")
else:
    var3 = var1/var2

J'espère que cela a aidé! Choisissez le choix que vous désirez (ils sont tous les deux identiques).

2
Christian

Essaye ça:

df['one']/(df['two'] +.000000001)
2
Merlin
df['one'].divide(df['two'])

Code:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.Rand(5,2), columns=list('ab'))
df.loc[[1,3], 'b'] = 0
print(df)

print(df['a'].divide(df['b']))

Résultat:

    a           b
0   0.517925    0.305973
1   0.900899    0.000000
2   0.414219    0.781512
3   0.516072    0.000000
4   0.841636    0.166157

0    1.692717
1         inf
2    0.530023
3         inf
4    5.065297
dtype: float64
1
Kartik