Есть ли способ написать быстрые вложенные циклы в python? - PullRequest
0 голосов
/ 04 февраля 2020

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

Другими словами, у меня есть список с 25 векторами присутствия / отсутствия (заполненный 0 и ОДИН 1) и список из 25 кадров данных (также заполненный 0 и 1). Векторы и кадры данных расположены в итерируемом порядке, что означает, что veclist [0] соответствует номеру столбца в PAM [0] и так далее. Функция имеет вложенный l oop, с внешним l oop, выполняющим кадры данных по порядку, и внутренним l oop, выполняющим строки (находит, в какой строке переменные встречаются в кадре данных для всех 25 переменных, и дает его значение)

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

Список векторов выглядит так:

import numpy as np
import pandas as pd
import math

A = np.random.randint(1, size=6).reshape(1, 6)
B = np.random.randint(1, size=11).reshape(1, 11)
A[:,2]=1
B[:,7]=1
vec1 = pd.DataFrame(A, columns=["a","b","c","d","e","f"])
vec2 = pd.DataFrame(B, columns=["a","b","c","d","e","f","g","h","i","j","k"])
veclist=[vec1,vec2]
print(veclist[0])

и список фреймы данных выглядят так:

A2 = np.random.randint(2, size=600).reshape(100,6)
B2 = np.random.randint(2, size=1100).reshape(100,11)
df1 = pd.DataFrame(A2, columns=["a","b","c","d","e","f"])
df2 = pd.DataFrame(B2, columns=["a","b","c","d","e","f","g","h","i","j","k"])
dflist=[df1,df2]
print(dflist[0])

Это код для функции, которую я написал.

def find_distance(veclist,dflist):
    ncol=len(dflist)
    nrow=dflist[0].shape[0]
    distance=np.zeros((nrow,ncol))
    for k in range(ncol):
        pres=np.where(veclist[k]==1) #getting matching column (where the vector matches the header)
        PAM=dflist[k]
        for m in range(nrow):
            if (veclist[k].iloc[pres]==1).bool() & (PAM.iloc[m,pres[1]]==1).bool():
                a = 2
            else:
                a = 0

            if (veclist[k].iloc[pres]==1).bool() & (PAM.iloc[m,pres[1]]==0).bool():
                b = 1
            else:
                b = 0

            if (veclist[k].iloc[pres]==0).bool() & (PAM.iloc[m,pres[1]]==1).bool():
                c = 1
            else:
                c = 0

        d = (2 * a)/(2 * a + b + c)
        d = math.sqrt(1-d)
        distance[m,k]=d
    return distance

Эта функция работает: она делает все, что мне нужно. Тем не менее, это очень медленно. С моими реальными данными, это занимает до минуты, чтобы запустить внутренний l oop. Я больше знаком с R, где эта же функция запускается за считанные секунды. Итак, почему эта функция занимает до 25 минут для запуска в python?

Что я сделал не так?

Я предполагаю, что проблема в том, что код должен быть больше pythoni c. Я медленно мигрирую с R на python, и все еще испытываю некоторые трудности. Например, я не знаю, как покончить с вложенным l oop и использовать Numpy, поскольку все должно быть идеально согласовано и сохранено. Любая помощь с этой проблемой будет высоко ценится.

Я использую python 3.7 и IDE spyder.

...