В настоящее время я пытаюсь записать фрейм данных в таблицу 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)