Как я могу использовать векторизацию в моем скрипте Pandas для эффективности? - PullRequest
0 голосов
/ 26 октября 2018

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

По сути, у меня есть два файла ввода.Одна представляет собой список всех комбинаций для группы SNP, например, ниже для 3 SNP:

    AA   CC   TT
    AT   CC   TT
    TT   CC   TT
    AA   CG   TT
    AT   CG   TT
    TT   CG   TT
    AA   GG   TT
    AT   GG   TT
    TT   GG   TT
    AA   CC   TA
    AT   CC   TA
    TT   CC   TA
    AA   CG   TA
    AT   CG   TA
    TT   CG   TA
    AA   GG   TA
    AT   GG   TA
    TT   GG   TA
    AA   CC   AA
    AT   CC   AA
    TT   CC   AA
    AA   CG   AA
    AT   CG   AA
    TT   CG   AA
    AA   GG   AA
    AT   GG   AA
    TT   GG   AA

А вторая представляет собой таблицу, содержащую некоторую информацию для каждого SNP, в частности их журнал (ИЛИ) дляболезнь и частота аллеля риска:

SNP1             A       T       1.25    0.223143551314     0.97273 
SNP2             C       G       1.07    0.0676586484738    0.3     
SNP3             T       A       1.08    0.0769610411361    0.1136  

Ниже приведен мой основной код, в котором я рассчитываю рассчитать «балл» и «частоту» для каждого «профиля».Оценка представляет собой сумму log (OR) для каждого аллеля риска, присутствующего в профиле, в то время как частота - это частоты, умноженные вместе, предполагая равновесие Харди Вайнберга:

import pandas as pd

numbers = pd.read_csv(table2, sep="\t", header=None)

combinations = pd.read_csv(table1, sep=" ", header=None)

def score_freq(line):
    score=0
    freq=1
    for j in range(len(line)):
        if line[j][1] != numbers.values[j][1]:   # homozygous for ref
            score+=0
            freq*=(float(1-float(numbers.values[j][6]))*float(1-float(numbers.values[j][6])))
        elif line[j][0] != numbers.values[j][1] and line[j][1] == numbers.values[j][1]: # heterozygous
            score+=(float(numbers.values[j][5]))
            freq*=(2*(float(1-float(numbers.values[j][6]))*float(numbers.values[j][6])))
        elif line[j][0] == numbers.values[j][1]:   # homozygous for risk
            score+=2*(float(numbers.values[j][5]))
            freq*=(float(numbers.values[j][6])*float(numbers.values[j][6]))

        if freq < 1e-05:   # threshold to stop loop in interest of efficiency 
            break

    return pd.Series([score, freq])

combinations[['score', 'freq']] = combinations.apply(lambda row: score_freq(row), axis=1)
#combinations[['score', 'freq']] = score_freq(combinations.values) # vectorization?

print(combinations)

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

1 Ответ

0 голосов
/ 26 октября 2018

Я бы предложил использовать библиотеку NumPy Python, чтобы сделать ваш pd-скрипт более эффективным.Идея NumPy заключается в том, что вы можете использовать векторизацию, чтобы избежать циклов FOR и, следовательно, очень эффективно обрабатывать загрузки данных.Работая с Numpy, вы в основном конвертируете свои данные в массивы Numpy.Вы можете найти обширную документацию здесь .Чтобы ответить на ваш вопрос, вы можете выполнить математические операции над массивами numpy следующим образом:

a = np.array([1, 2, 3, 4])
a + 1                // to add 1 to every element in the array

a * 2                // to multiply each element in the array by 2

, что намного эффективнее, чем если бы вы использовали циклы FOR в чистом python.

Надеюсь, что этопомогает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...