1. #1
    Membre éprouvé Avatar de Mathusalem
    Profil pro
    Inscrit en
    décembre 2003
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2003
    Messages : 1 002
    Points : 959
    Points
    959

    Par défaut [Python 3.X] Calcul de différences

    Bonjour à tous,

    Je refais du Python après quelques années (et même un peu plus que ça ) et je galère un peu.

    J'ai un ensemble de portefeuilles (books) contenant des instruments financiers.
    Pour chaque jour et chaque book, je connais le résultat (PnL) en euros depuis le début de l'année (YtD = Year to Date). Le tout est ventilé par source.

    Mon objectif : calculer le gain journalier, autrement dit, le PnL Daily. PnLDaily(J) = PnLYtD(J) - PnLYtD(J-1)

    En m'aidant du net, j'ai identifié 2 méthodes pour faire ce calcul et fait fonctionné le tout avec des données bricolées.
    Cela donne ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    ''' Préparation des données '''
    import pandas as pd
    import numpy as np
    import random
    from itertools import product
     
    random.seed(1)
    np.random.seed(2)
     
    dates = pd.date_range(start='2013-10-01', periods=10).to_native_types()
     
    Books = ['Book%d' % i for i in range(3)]
     
    # make a list of all the possible (date, ticker) tuples
    pairs = list(product(dates, Books))
     
    random.shuffle(pairs)
     
    PnL = np.random.rand(len(pairs)) * 10000
     
    mydates, myBooks = zip(*pairs)
    data = pd.DataFrame({'date': mydates, 'book': myBooks, 'PnL':PnL})
    Méthode de calcul 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    data2 = data.pivot_table(index=['date'], columns=['book'],values='PnL', aggfunc=[np.sum])
    print(data2.diff())
    Nom : 20170616 150939 Spyder (Python 3.5).png
Affichages : 53
Taille : 13,8 Ko

    Méthode de calcul 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    data3 = data.copy()
    data3.sort_values(by=['book','date'],inplace=True)
    data3['PnLDaily'] = data3.groupby('book')['PnL'].transform(pd.Series.diff)
    print(data3)
    Nom : 20170616 151136 Spyder (Python 3.5).png
Affichages : 47
Taille : 31,3 Ko


    Ne sachant pas quelle méthode choisir, je souhaite refaire l'exercice avec de vraies données pour comparer les performances.
    C'est là que les choses se gâtent...


    Je récupère mes données en base
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    sql = '''SELECT date, book, Filiere, PnL_Eur bla bla bla'' % (lDates, lBooks)'''
    dfRescum = psql.read_sql(sql, con)
     
    sql = '''SELECT date, book, Filiere, PnL_Eur  bla bla bla'' % (lDates, lBooks)'''
    dfCorrect = psql.read_sql(sql, con)
    Mes données étant dans 2 tables, je fais l'union et je somme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dfPnL = pd.concat([dfRescum,dfCorrect],ignore_index=True)
    dfPnLAgg = dfPnL.groupby(['AsofDate','Book']).agg({'PnL_Eur' : np.sum})
    Problème : maintenant en appliquant mes 2 méthodes présentées ci-dessous, ça plante dans les 2 cas.
    Il y a quelque chose dans la structure de données obtenue que je ne comprends pas et qui fait tout coincer.

    Nom : 20170616 151941 Spyder (Python 3.5).png
Affichages : 46
Taille : 21,7 Ko

    Désolé pour la log...
    methode1.diff()
    Traceback (most recent call last):

    File "<ipython-input-214-694d35795766>", line 1, in <module>
    methode1.diff()

    File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\frame.py", line 4059, in diff
    new_data = self._data.diff(n=periods, axis=bm_axis)

    File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\internals.py", line 3174, in diff
    return self.apply('diff', **kwargs)

    File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\internals.py", line 3056, in apply
    applied = getattr(b, f)(**kwargs)

    File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\internals.py", line 1041, in diff
    new_values = algos.diff(self.values, n, axis=axis)

    File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\algorithms.py", line 1251, in diff
    out_arr[res_indexer] = arr[res_indexer] - arr[lag_indexer]

    TypeError: unsupported operand type(s) for -: 'str' and 'str'




    Quand je tente la méthode 2, même genre de soucis.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    methode2 = dfPnLAgg.copy()
    methode2['PnLDaily'] = dfPnLAgg.groupby('Book')['PnL_Eur'].transform(pd.Series.diff)
    methode2['PnLDaily'] = dfPnLAgg.groupby('Book')['PnL_Eur'].transform(pd.Series.diff)
    Traceback (most recent call last):

    File "<ipython-input-216-2c608f326c29>", line 1, in <module>
    methode2['PnLDaily'] = dfPnLAgg.groupby('Book')['PnL_Eur'].transform(pd.Series.diff)

    File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\groupby.py", line 2831, in transform
    res = wrapper(group)

    File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\groupby.py", line 2828, in <lambda>
    wrapper = lambda x: func(x, *args, **kwargs)

    File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\series.py", line 1459, in diff
    result = algos.diff(_values_from_object(self), periods)

    File "C:\Users\mathu\AppData\Roaming\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\pandas\core\algorithms.py", line 1251, in diff
    out_arr[res_indexer] = arr[res_indexer] - arr[lag_indexer]

    TypeError: unsupported operand type(s) for -: 'str' and 'str'

    Voila voila, je suis un peu gêné de vous coller mes logs d'erreurs, mais je ne sais pas où chercher.


    Bien amicalement.
    Mathu

  2. #2
    Nom
    Nom est déconnecté
    Membre actif
    Profil pro
    Inscrit en
    octobre 2005
    Messages
    619
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : octobre 2005
    Messages : 619
    Points : 241
    Points
    241

    Par défaut

    Vu l'erreur, je pense que le résultat de la requête est considéré comme étant des chaines de caractères (meme si la colonne est de type int)

    Un simple cast pourrai peut être te débloquer
    Le savoir est une arme alors soyons armés

  3. #3
    Membre éprouvé Avatar de Mathusalem
    Profil pro
    Inscrit en
    décembre 2003
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2003
    Messages : 1 002
    Points : 959
    Points
    959

    Par défaut

    Bien vu.

    Problème réglé avec cette conversion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dfCorrect['PnL_Eur'] = dfCorrect['PnL_Eur'].apply(pd.to_numeric)
    dfRescum['PnL_Eur'] = dfRescum['PnL_Eur'].apply(pd.to_numeric)

  4. #4
    Membre éprouvé Avatar de Mathusalem
    Profil pro
    Inscrit en
    décembre 2003
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : décembre 2003
    Messages : 1 002
    Points : 959
    Points
    959

    Par défaut

    Enfin, la méthode 2 s'avère bien plus performante sur un gros volume de données.


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Time] Comment calculer la différence entre deux Time?
    Par adil_vpb dans le forum java.util
    Réponses: 1
    Dernier message: 14/03/2007, 17h24
  2. Réponses: 3
    Dernier message: 01/02/2007, 14h50
  3. Réponses: 4
    Dernier message: 18/10/2006, 15h48
  4. Calcul de différence dans une requête
    Par Le Pharaon dans le forum Langage SQL
    Réponses: 8
    Dernier message: 19/05/2005, 13h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo