优化Pandas-df以计算单词列表中的位置字符频率



我正在创建一个pandas数据帧,用于跟踪给定单词列表中每个位置的字符频率。然而,对于较大的列表+较长的单词,运行时间非常慢(由于嵌套循环,algo使用O(n^2(运行(

有人对算法进行了优化吗?或者可以给我指一个已经针对这样的事情进行了优化的矢量化类型函数吗?

再版:

import pandas as pd
word_list = ['despairing','stationary','presenting','copernicus','wheelchair']
word_length = len(word_list[0])
letters  = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
positions = ["pos" + f"{x}" for x in range(1, word_length+1)]
count_matrix = pd.DataFrame(0, columns = positions, index = letters)
for word in range(0, len(word_list)):
for letter in range(0, word_length):
count_matrix.loc[word_list[word][letter], f'pos{letter+1}'] += 1
count_matrix

我相信f2(...)是对原始算法的改进。(f1(...)是您的算法,封装为一个函数。(

当我们的两个函数都循环通过单词和字母时,这实际上是O(n*k),其中n是单词的数量,k是单词的最大长度。你必须处理每个单词中的每个字母,所以在运行时没有办法。但是,我认为f2(...)有一些改进可以加快执行速度,包括在处理完所有字母之后才创建DataFrame。(我认为在pandas DataFrame中查找和编辑单个值通常是缓慢和不鼓励的。(

这个新函数还可以为任何长度的单词添加单词(而原来的函数不会为比第一个单词长的单词捕获任何字符位置(。

在ipython或Jupyter笔记本电脑中,您可以运行%timeit f1(word_list)%timeit f2(word_list)来查看每个函数运行所需的时间。

import pandas as pd
def f1(word_list):
word_length = len(word_list[0])
letters  = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
positions = ["pos" + f"{x}" for x in range(1, word_length+1)]
count_matrix = pd.DataFrame(0, columns = positions, index = letters)
for word in range(0, len(word_list)):
for letter in range(0, word_length):
count_matrix.loc[word_list[word][letter], f'pos{letter+1}'] += 1
return count_matrix
def f2(word_list):
d = {}
letters  = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
for letter in letters:
d[letter] = {}
for word in word_list:
for i, letter in enumerate(word):
if i not in d[letter]:
d[letter][i] = 1
else:
d[letter][i] += 1

count_matrix = pd.DataFrame(d)
# making the DataFrame resemble your output
count_matrix = count_matrix.sort_index()
count_matrix = count_matrix.T
count_matrix = count_matrix.fillna(0)
count_matrix = count_matrix.astype(int)
count_matrix.columns = ["pos" + str(col+1) for col in count_matrix.columns]
return count_matrix

最新更新