Как я могу заставить мою программу использовать несколько ядер моей системы в python? - PullRequest
0 голосов
/ 19 сентября 2018

Я хотел запустить свою программу на всех ядрах, которые у меня есть.Ниже приведен код, который я использовал в своей программе (которая является частью моей полной программы. Каким-то образом удалось написать рабочий процесс).

def ssmake(data):
    sslist=[]
    for cols in data.columns:
        sslist.append(cols)
    return sslist

def scorecal(slisted):
    subspaceScoresList=[]
    if __name__ == '__main__':
        pool = mp.Pool(4)
            feature,FinalsubSpaceScore = pool.map(performDBScan, ssList)
            subspaceScoresList.append([feature, FinalsubSpaceScore])

        #for feature in ssList:
            #FinalsubSpaceScore = performDBScan(feature)
            #subspaceScoresList.append([feature,FinalsubSpaceScore])
        return subspaceScoresList

def performDBScan(subspace):
    minpoi=2
    Epsj=2
    final_data = df[subspace]
    db = DBSCAN(eps=Epsj, min_samples=minpoi, metric='euclidean').fit(final_data)
        labels = db.labels_
    FScore = calculateSScore(labels)
    return subspace, FScore

def calculateSScore(cluresult):
    score = random.randint(1,21)*5
    return score

def StartingFunction(prvscore,curscore,fe_select,df):
    while prvscore<=curscore:
        featurelist=ssmake(df)
        scorelist=scorecal(featurelist)

a = {'a' : [1,2,3,1,2,3], 'b' : [5,6,7,4,6,5], 'c' : ['dog', 'cat', 'tree','slow','fast','hurry']}
df2 = pd.DataFrame(a)
previous=0
current=0
dim=[]
StartingFunction(previous,current,dim,df2)

У меня был цикл for в scorecal(slisted) метод, который был прокомментирован, берет каждый столбец для выполнения DBSCAN и должен рассчитать оценку для этого конкретного столбца на основе результата (но я попытался использовать случайную оценку здесь в примере).Этот цикл заставляет мой код работать дольше.Поэтому я попытался распараллелить каждый столбец DataFrame для выполнения DBSCAN на тех ядрах, которые у меня были в моей системе, и написал код описанным выше способом, который не дает нужного мне результата.Я был новичком в этой многопроцессорной библиотеке.Я не был уверен с размещением '__main__' в моей программе.Я также хотел бы знать, есть ли какой-либо другой способ в Python для параллельной работы.Любая помощь приветствуется.

1 Ответ

0 голосов
/ 20 сентября 2018

В вашем коде есть все, что нужно для работы на многоядерном процессоре, использующем более одного ядра.Но это беспорядок.Я не знаю, какую проблему вы пытаетесь решить с помощью кода.Также я не могу запустить его, так как я не знаю, что такое DBSCAN.Чтобы исправить свой код, вы должны выполнить несколько шагов.

Функция scorecal():

def scorecal(feature_list):
    pool = mp.Pool(4)
    result = pool.map(performDBScan, feature_list)
    return result

result - список, содержащий все результаты, возвращаемые performDBSCAN().Вам не нужно заполнять список вручную.

Основная часть программы:

# imports

# functions

if __name__ == '__main__':
    # your code after functions' definition where you call StartingFunction()

Я создал очень упрощенную версию вашего кода (пул с 4 процессами для обработки 8 столбцовмои данные) с пустышкой для циклов (для выполнения связанных с процессором операций) и попробовал его.Я получил 100% загрузки процессора (у меня 4-ядерный процессор i5), что, естественно, привело к примерно в 4 раза более быстрым вычислениям (20 секунд против 74 секунд) по сравнению с реализацией одного процесса в цикле for.

EDIT.

Полный код, который я использовал для многопроцессорной обработки (я использую Anaconda (Spyder) / Python 3.6.5 / Win10):

import multiprocessing as mp
import pandas as pd
import time


def ssmake():
    pass


def score_cal(data):
    if True:
        pool = mp.Pool(4)
        result = pool.map(
            perform_dbscan,
            (data.loc[:, col] for col in data.columns))
    else:
        result = list()
        for col in data.columns:
            result.append(perform_dbscan(data.loc[:, col]))
    return result


def perform_dbscan(data):
    assert isinstance(data, pd.Series)
    for dummy in range(5 * 10 ** 8):
        dummy += 0
    return data.name, 101


def calculate_score():
    pass


def starting_function(data):
    print(score_cal(data))


if __name__ == '__main__':

    data = {
        'a': [1, 2, 3, 1, 2, 3],
        'b': [5, 6, 7, 4, 6, 5],
        'c': ['dog', 'cat', 'tree', 'slow', 'fast', 'hurry'],
        'd': [1, 1, 1, 1, 1, 1]}
    data = pd.DataFrame(data)

    start = time.time()
    starting_function(data)
    print(
        'running time = {:.2f} s'
        .format(time.time() - start))
...