Проблема совместимости ibm_boto3 с scikit-learn в Mac OS - PullRequest
0 голосов
/ 04 мая 2018

У меня есть приложение Python 3.6, которое использует scikit-learn, развернутое в IBM Cloud (Cloud Foundry). Работает нормально. Моя локальная среда разработки - Mac OS High Sierra.

Недавно я добавил в приложение функциональность IBM Cloud Object Storage (ibm_boto3). Сама функциональность COS работает нормально. Я могу нормально загружать, скачивать, перечислять и удалять объекты, используя библиотеку ibm_boto3.

Странно, но часть приложения, которая использует scikit-learn, теперь зависает.

Если я закомментирую операторы ibm_boto3 import (и соответствующий код), код scikit-learn работает нормально.

Еще более озадачивает проблема, возникающая только на локальной машине разработки под управлением OS X. Когда приложение развертывается в IBM Cloud, оно работает нормально - и scikit-learn, и ibm_boto3 работают хорошо бок о бок.

На данный момент наша единственная гипотеза состоит в том, что библиотека ibm_boto3 каким-то образом обнаруживает известную проблему в scikit-learn (см. this - параллельная версия алгоритма K-средних не работает, когда numpy использует ускоритель на OS X). Обратите внимание, что мы сталкиваемся с этой проблемой только после добавления ibm_boto3 в проект.

Однако нам нужно иметь возможность протестировать локальный хост перед развертыванием в IBM Cloud. Есть ли известные проблемы совместимости между ibm_boto3 и scikit-learn в Mac OS?

Какие-нибудь предложения о том, как этого избежать на компьютере разработчика?

Приветствие.

1 Ответ

0 голосов
/ 07 мая 2018

До сих пор не было никаких известных проблем совместимости. :)

В какой-то момент возникли некоторые проблемы с библиотеками vanilla SSL, которые поставляются с OSX, но если вы можете читать и записывать данные, это не проблема.

Используете ли вы учетные данные HMAC ? Если это так, мне любопытно, продолжит ли это поведение, если вы используете оригинальную библиотеку boto3 вместо IBM fork.

Вот простые примеры, которые показывают, как вы можете использовать pandas с оригинальным boto3:

import boto3  # package used to connect to IBM COS using the S3 API
import io  # python package used to stream data
import pandas as pd  # lightweight data analysis package

access_key = '<access key>'
secret_key = '<secret key>'
pub_endpoint = 'https://s3-api.us-geo.objectstorage.softlayer.net'
pvt_endpoint = 'https://s3-api.us-geo.objectstorage.service.networklayer.com'
bucket = 'demo'  # the bucket holding the objects being worked on.
object_key = 'demo-data'  # the name of the data object being analyzed.
result_key = 'demo-data-results'  # the name of the output data object.


# First, we need to open a session and create a client that can connect to IBM COS.
# This client needs to know where to connect, the credentials to use,
# and what signature protocol to use for authentication. The endpoint
# can be specified to be public or private.
cos = boto3.client('s3', endpoint_url=pub_endpoint,
                   aws_access_key_id=access_key,
                   aws_secret_access_key=secret_key,
                   region_name='us',
                   config=boto3.session.Config(signature_version='s3v4'))

# Since we've already uploaded the dataset to be worked on into cloud storage,
# now we just need to identify which object we want to use. This creates a JSON
# representation of request's response headers.
obj = cos.get_object(Bucket=bucket, Key=object_key)

# Now, because this is all REST API based, the actual contents of the file are
# transported in the request body, so we need to identify where to find the
# data stream containing the actual CSV file we want to analyze.
data = obj['Body'].read()

# Now we can read that data stream into a pandas dataframe.
df = pd.read_csv(io.BytesIO(data))

# This is just a trivial example, but we'll take that dataframe and just
# create a JSON document that contains the mean values for each column.
output = df.mean(axis=0, numeric_only=True).to_json()

# Now we can write that JSON file to COS as a new object in the same bucket.
cos.put_object(Bucket=bucket, Key=result_key, Body=output)
...