Я пытаюсь мультипроцессировать импорт панд read_sq()
с помощью чанков. Конечная цель - найти расстояние между двумя латами. Поскольку я работаю в ноутбуке Jupyter, функции для multiprocessing
должны быть в отдельном файле. Этот файл выглядит так:
import pandas as pd
from sqlalchemy import event, create_engine
from math import radians, cos, sin, asin, sqrt
import numpy as np
engine = create_engine('engine-path')
data = pd.read_sql("SELECT * from SCHEMA.TABLE", engine)
def cartesian_product_simplified(left, right):
la, lb = len(left), len(right)
ia2, ib2 = np.broadcast_arrays(*np.ogrid[:la,:lb])
return pd.DataFrame(np.column_stack([left.values[ia2.ravel()], right.values[ib2.ravel()]]))
def haversine_np(lon1, lat1, lon2, lat2):
lon1, lat1, lon2, lat2 = map(np.radians, [lon1, lat1, lon2, lat2])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = np.sin(dlat/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2.0)**2
c = 2 * np.arcsin(np.sqrt(a))
m = 3956.269 * c
return m
def getDistance(chunk):
df = cartesian_product_simplified(chunk, data)
df = df.rename(columns={1:'lat1',2:'lon1',6:'lat2',7:'lon2'})
df = df.astype({"lat1": float,"lon1": float,"lat2": float,"lon2": float})
m = haversine_np(df['lon1'],df['lat1'],df['lon2'],df['lat2'])
dist = pd.DataFrame(m.values)
result = df.join(dist)
result = result.rename(columns={0:'dist'})
result = result[result['dist']<=3]
return result
Основной блокнот выглядит так:
import pandas as pd
from dist_func import getDistance
from multiprocessing import Pool
if __name__ == '__main__':
global result
p = Pool(20)
for chunk in pd.read_sql("select top 10 * from SCHEMA.SecondTable", engine, chunksize=1):
result = p.map(getDistance, chunk)
p.terminate()
p.join()
Это приводит к следующей трассировке:
Traceback (most recent call last):
File "C:\Users\filepath\anaconda\lib\multiprocessing\pool.py", line 119, in worker
result = (True, func(*args, **kwds))
File "C:\Users\filepath\anaconda\lib\multiprocessing\pool.py", line 44, in mapstar
return list(map(*args))
File "C:\Users\filepath\dist_func.py", line 30, in getDistance
df = cartesian_product_simplified(chunk, vendor_geo)
File "C:\Users\filepath\dist_func.py", line 18, in cartesian_product_simplified
return pd.DataFrame(np.column_stack([left.values[ia2.ravel()], right.values[ib2.ravel()]]))
AttributeError: 'str' object has no attribute 'values'
Указывает на функцию cartesian_product_simplified
, которая входит в функцию getDistance
. Тем не менее, когда я удаляю многопроцессорность и просто выполняю чанк с помощью запроса read_sql()
, как этот ...
for chunk in pd.read_sql("select top 100 * from SCHEMA.SecondTable", engine, chunksize=10):
df = cartesian_product_simplified(chunk, data)
df = df.astype({"lat1": float,"lon1": float,"lat2": float,"lon2": float})
df = df.astype({"lat1": float,"lon1": float,"lat2": float,"lon2": float})
m = haversine_np(df['lon1'],df['lat1'],df['lon2'],df['lat2'])
dist = pd.DataFrame(m.values)
result = df.join(dist)
result = result.rename(columns={0:'dist'})
result = result[result['dist']<=3]
df_list.append(result)
... такая ошибка не выдается. Это с использованием точно таких же функций. Почему эта ошибка возникает, когда кажется, что функция получает два фрейма данных и работает без многопроцессорной обработки?