Pandas производительность инициализации данных - PullRequest
1 голос
/ 22 апреля 2020

Меня удивляет, как медленно инициализируется пустой объект pandas данных:

import pandas as pd 
from utils import Timer

with Timer.Timer("test"):
    with Timer.Timer("set"):
        columns = pd.DatetimeIndex(['2018-02-12', '2018-03-12', '2018-04-10', '2018-07-10','2019-01-10', '2020-01-10', '2021-01-10', '2022-01-10',  
                          '2023-01-10', '2024-01-10', '2025-01-10', '2026-01-10', '2027-01-10', '2028-01-10', '2030-01-10', '2033-01-10',
                          '2038-01-10', '2043-01-10', '2048-01-10'],dtype='datetime64[ns]', name='maturity', freq=None)
        flowKeys = ["flowType", "flowDate"]
        rate = 2/100
        date2 = datetime(2020,1,1)
        date1 = datetime(2000,1,1)
        #dataframes
        flows = None 
        dNDF = None 
        dF = None    

    # dataframe init 
    with Timer.Timer("init"):
        flows = pd.DataFrame(None, columns = flowKeys+["flowValue"]).set_index(flowKeys)
        dNDF = pd.DataFrame(None, columns = flowKeys+columns.tolist()).set_index(flowKeys)
    # lending flow
    with Timer.Timer("add1"):
        flows.loc[("CAP", date1),"flowValue"] = -1
    with Timer.Timer("add2"):
        dNDF.loc[("CAP", date1),:] = 0
        # reimbursement of the capital flow
    with Timer.Timer("add3"):
        flows.loc[("CAP", date2),"flowValue"] = 1
    with Timer.Timer("add4"):
        dNDF.loc[("CAP", date2),:] = 0
        # interest flow 
    with Timer.Timer("add5"):
        flows.loc[("INT", date2),"flowValue"] = rate * (date2 - date1).days/360
    with Timer.Timer("add6"):
        dNDF.loc[("INT", date2),:]= 0 

При регистрации производительности я получаю следующие результаты: инициализация 2 пустых кадров данных занимает 10 мс и приблизительно добавить одну строку в вышеупомянутом кадре данных.

[set]
Elapsed: 0.326904296875
[init]
Elapsed: 11.828125
[add1]
Elapsed: 3.95703125
[add2]
Elapsed: 10.489013671875
[add3]
Elapsed: 2.76513671875
[add4]
Elapsed: 9.325927734375
[add5]
Elapsed: 3.031005859375
[add6]
Elapsed: 10.52294921875
[test]
Elapsed: 52.6328125

Есть ли способ радикально улучшить скорость этого кода? Можно воспроизвести проблему, скопировав / вставив код, но модуль таймера, как показано ниже, контролирует время выполнения в мс:

import time

class Timer(object):
    def __init__(self, name=None):
        self.name = name

    def __enter__(self):
        self.tstart = time.time()

    def __exit__(self, type, value, traceback):
        if self.name:
            print('[%s]' % self.name,)
        print('Elapsed: %s' % (1000*time.time() - 1000*self.tstart))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...