Панды - самая быстрая дата-серия для струн - PullRequest
0 голосов
/ 16 октября 2019

В настоящее время я пытаюсь записать фрейм данных в таблицу MySQL.

Я написал метод для сериализации столбца в фрейме данных.

 def serializeSerie(serie, valueType):
    result = serie.copy()
    result = serie.astype('object', errors='ignore')

    if valueType == 'datetime64[ns]':
        result[serie.notnull()] = serie[serie.notnull()].dt.strftime('%Y-%m-%d %H:%M:%S.%f')

    if valueType == 'timedelta64[ns]':
        seconds = serie[serie.notnull()].dt.total_seconds().values
        hours, rem = np.divmod(seconds, 3600)
        minutes, seconds = np.divmod(rem, 60)

        hours = np.reshape(hours, (len(hours),1))
        minutes = np.reshape(minutes, (len(minutes),1))
        seconds = np.reshape(seconds, (len(seconds),1))
        m = np.concatenate((hours, minutes, seconds), axis=1)

        def toTime(r):
            return '{:02d}:{:02d}:{:0.5f}'.format(int(r[0]), int(r[1]), r[2])

        result[serie.notnull()] = np.apply_along_axis(toTime, 1, m)

    result = result.where(result.notnull(), None)

    return result

Эта версия методапопытка векторизации ячейки методом сериализации ячейки.

Как вы можете видеть, я использую нативные типы преобразования для большей части объекта (целые числа, числа с плавающей запятой, строки ...). Таким образом, я получил в 2700+ раз больше на этих типах.

Проблемы возникают с типами, которые нуждаются в специфическом преобразовании (например, datetime, timedelta). Я искал в Интернете и документацию как панд и numpy и пришел с вышеуказанным решением. Это сокращает время обработки примерно в 20 раз.

Я удивлен, что не могу найти способ улучшить эти «сложные» типы данных.

Могу ли я прийти с чем-нибудьболее эффективно?

Метод сериализации по ячейкам

def serialize(value, valueType):
    if value is None or pd.isnull(value):
        return None

    if valueType in ['int64', 'int32', 'int16']:
        return int(value)

    if valueType in ['float64']:
        return float(value)

    if valueType == 'datetime64[ns]':
        return value.strftime('%Y-%m-%d %H:%M:%S.%f')

    if valueType == 'bool':
        return value

    if valueType == 'timedelta64[ns]':
        hours, rem = divmod(value.seconds, 3600)
        minutes, seconds = divmod(rem, 60)
        return '{}:{}:{}'.format(hours, minutes, seconds)

    return str(value)   

Спасибо за потраченное время

Редактировать: Тестировать фрейм данных

df = pandas.DataFrame({ 
    "int": range(0, 100000, 1) ,
    "date": pandas.to_datetime(range(0, 100000, 1)),
    "time": pandas.to_timedelta(range(0, 100000, 1))
})

start = time.time()

for column in df.columns:
    try:
        df[column] = serializeSerie(df[column], df[column].dtype)
    except:
        print("An error occured while parsing the dataframe's data on column `{}`".format(column))
        raise

end = time.time()

elapsedTime = (end - start) * 1000

print('Serialize data in ', elapsedTime)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...