У объекта 'str' нет атрибута 'values' - объект не выглядит как строка - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь мультипроцессировать импорт панд 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)

... такая ошибка не выдается. Это с использованием точно таких же функций. Почему эта ошибка возникает, когда кажется, что функция получает два фрейма данных и работает без многопроцессорной обработки?

1 Ответ

0 голосов
/ 04 мая 2019

Я не знаю причину, но выбор меньшего количества разделов устранил эту проблему для меня в моем собственном наборе данных. Таким образом, ошибка может быть прямо или косвенно связана с количеством выбранных разделов или отношением разделов к строкам в вашем наборе данных. Для больших наборов данных у меня не было этой проблемы.

...