Я написал функцию, которая берет набор из нескольких переменных и сопоставляет его со списком фреймов данных (который содержит 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.