Я занимаюсь анализом данных в Python. У меня есть ~ 15 тыс. Финансовых продуктов, идентифицированных кодом ISIN, и ~ 15 столбцов ежедневных данных для каждого из них. Я хотел бы легко и быстро получить доступ к данным с помощью кода ISIN.
Данные находятся в БД MySQL. Пока что на стороне Python я работаю с Pandas DataFrame.
Первым делом я использовал pd.read_sql для загрузки DF напрямую из базы данных. Однако это относительно медленно. Затем я попытался загрузить полную базу данных в одном DF и сериализовать ее в файл рассола. Загрузка файла рассола происходит быстро, несколько секунд. Однако при запросе для отдельного продукта производительность такая же, как если бы я запрашивал базу данных SQL. Вот некоторый код:
import pandas as pd
from sqlalchemy import create_engine, engine
from src.Database import Database
import time
import src.bonds.database.BondDynamicDataETL as BondsETL
database_instance = Database(Database.get_db_instance_risk_analytics_prod())
engine = create_engine(
"mysql+pymysql://"
+ database_instance.get_db_user()
+ ":"
+ database_instance.get_db_pass()
+ "@"
+ database_instance.get_db_host()
+ "/"
+ database_instance.get_db_name()
)
con = engine.connect()
class DataBase:
def __init__(self):
print("made a DatBase instance")
def get_individual_bond_dynamic_data(self, isin):
return self.get_individual_bond_dynamic_data_from_db(isin, con)
@staticmethod
def get_individual_bond_dynamic_data_from_db(isin, connection):
df = pd.read_sql(
"SELECT * FROM BondDynamicDataClean WHERE isin = '"
+ isin
+ "' ORDER BY date ASC",
con=connection,
)
df.set_index("date", inplace=True)
return df
class PickleFile:
def __init__(self):
print("made a PickleFile instance")
df = pd.read_pickle("bonds_pickle.pickle")
# df.set_index(['isin', 'date'], inplace=True)
self.data = df
print("loaded file")
def get_individual_bond_dynamic_data(self, isin):
result = self.data.query("isin == '@isin'")
return result
fromPickle = PickleFile()
fromDB = DataBase()
isins = BondsETL.get_all_isins_with_dynamic_data_from_db(
connection=con,
table_name=database_instance.get_bonds_dynamic_data_clean_table_name(),
)
isins = isins[0:50]
start_pickle = time.time()
for i, isin in enumerate(isins):
x = fromPickle.get_individual_bond_dynamic_data(isin)
print("pickle: " + str(i))
stop_pickle = time.time()
for i, isin in enumerate(isins):
x = fromDB.get_individual_bond_dynamic_data(isin)
print("db: " + str(i))
stop_db = time.time()
pickle_t = stop_pickle - start_pickle
db_t = stop_db - stop_pickle
print("pickle: " + str(pickle_t))
print("db: " + str(db_t))
print("ratio: " + str(pickle_t / db_t))
Это приводит к:
маринованные огурцы: 7,636280059814453
дБ: 6,167926073074341
соотношение: 1,23806283819615
Также, как ни странно, установка индекса на DF (раскомментирование строки в конструкторе) замедляет все!
Я думал о попытке https://www.pytables.org/index.html в качестве альтернативы Пандам. Любые другие идеи или комментарии?
Привет,
Георгий