#python #pandas
#python #pandas
Вопрос:
У меня есть фрейм данных, который содержит примерно 100 000 строк. столбец «последовательность» во фрейме данных имеет некоторую длинную строку в качестве своего значения. Я в основном хочу вычислить вхождение substring в столбце «последовательность» с перекрытием (т. Е. если значение равно aaaaaa, а подстрока равна aa, то частота должна быть 5, а не 3).
Ниже приведен воспроизводимый код, который похож на реальный код.
import pandas as pd
import re
import itertools
import time
from random import choice
# generate 100,000 random strings of fixed size for demo purpose
alphabet = "abcdefghijk"
str_list = []
for i in range(100000):
str_list.append(''.join(choice(alphabet) for i in range(100)))
# make pandas dataframe
df = pd.DataFrame(columns=['sequence'], data=str_list)
# get a list of substrings to count its frequency in the dataframe
# for the sake of demo, make substrings from "alphabet" with length of 3
# actual application can have up to substrings of length 5 (i.e. 11^5 substrings)
words = [''.join(p) for p in itertools.product(alphabet, repeat=3))]
# calculate frequency of words in the dataframe
for word in words:
tic = time.time()
df['frequency'] = df['sequence'].apply(lambda x: len(re.findall('(?={0})'.format(word), x)))
print("{}s took for one iteration".format(time.time() - tic))
Обратите внимание, что встроенная функция Pandas, «pd.Series.str.count», будет подсчитывать вхождение подстроки без перекрытий, поэтому мне пришлось использовать apply в сочетании с регулярным выражением.
Проблема в том, что на моем компьютере для вычисления частоты для каждой подстроки требуется ~ 0,5 секунды, а поскольку количество подстрок составляет от 11 ^ 3 до 11 ^ 5, в худшем случае это может занять до 80 000 секунд (или 11 часов).
Кажется, что операция lambda замедляет время вычисления, поскольку она должна быть скомпилирована на python вместо cython (который, бесспорно, быстрее, чем python), но я не знаю, как еще это сделать.
Мне было интересно, есть ли способы ускорить эту операцию?
p.s. Я использую Python 3.5.2