我希望优化我使用python
时遇到的大数据解析问题的性能。以防有人感兴趣:下面显示的数据是六种灵长类动物全基因组DNA序列比对的片段。
目前,我知道如何处理这类问题的最好方法是打开我的~250(大小20-50MB)文件,逐行循环并提取我想要的数据。格式(如示例所示)是相当规则的,尽管在每个10000到100000行的线段上都有重要的更改。循环工作很好,但速度很慢。
我最近一直在使用numpy
来处理大量(>10gb)的数值数据集,我真的很惊讶我能以多快的速度在数组上执行不同的计算。我想知道是否有一些高性能的解决方案来处理格式化的文本,以避免冗长的循环?
我的文件包含多个具有以下模式的段
<MULTI-LINE HEADER> # number of header lines mirrors number of data columns
<DATA BEGIN FLAG> # the word 'DATA'
<DATA COLUMNS> # variable number of columns
<DATA END FLAG> # the pattern '//'
<EMPTY LINE>
# key to the header fields:
# header_flag chromosome segment_start segment_end quality_flag chromosome_data
SEQ homo_sapiens 1 11388669 11532963 1 (chr_length=249250621)
SEQ pan_troglodytes 1 11517444 11668750 1 (chr_length=229974691)
SEQ gorilla_gorilla 1 11607412 11751006 1 (chr_length=229966203)
SEQ pongo_pygmaeus 1 218866021 219020464 -1 (chr_length=229942017)
SEQ macaca_mulatta 1 14425463 14569832 1 (chr_length=228252215)
SEQ callithrix_jacchus 7 45949850 46115230 1 (chr_length=155834243)
DATA
GGGGGG
CCCCTC
...... # continue for 10-100 thousand lines
//
SEQ homo_sapiens 1 11345717 11361846 1 (chr_length=249250621)
SEQ pan_troglodytes 1 11474525 11490638 1 (chr_length=229974691)
SEQ gorilla_gorilla 1 11562256 11579393 1 (chr_length=229966203)
SEQ pongo_pygmaeus 1 219047970 219064053 -1 (chr_length=229942017)
DATA
CCCC
GGGG
.... # continue for 10-100 thousand lines
//
<ETC>
homo_sapiens
和
macaca_mulatta
的段,并且字段6(我在上面的注释中称之为质量标志)对于每个物种都等于“1”。因为
macaca_mulatta
不会出现在第二个示例中,所以我将完全忽略此段。
segment_start
和
segment_end
坐标,所以在存在
homo_sapiens
的段中,我将记录这些字段并将它们用作
homo_sapiens
的键。
dict()
还告诉我
segment_start
的第一个位置坐标,当前段中每行数据的第一个位置坐标严格增加1。
homo_sapiens
和
homo_sapiens
的字母(DNA碱基)。出现
macaca_mulatta
和
homo_sapiens
的标题行(即第一个示例中的1和5)对应于表示其各自序列的数据列。
# homo_sapiens_coordinate homo_sapiens_base macaca_mulatta_base
11388669 G G
11388670 C T
macaca_mulatta
和
homo_sapiens
信息的段,我将从标题和两个不匹配的位置记录
macaca_mulatta
的开始和结束。最后,一些职位有“差距”或质量较低的数据,即。
aaa--A
homo_sapiens
和
homo_sapiens
都有有效基(必须在集合
macaca_mulatta
中)的位置进行记录,因此我考虑的最后一个变量是每段有效基的计数器。
{(segment_start=i, segment_end=j, valid_bases=N): list(mismatch positions),
(segment_start=k, segment_end=l, valid_bases=M): list(mismatch positions), ...}
def human_macaque_divergence(chromosome):
"""
A function for finding the positions of human-macaque divergent sites within segments of species alignment tracts
:param chromosome: chromosome (integer:
:return div_dict: a dictionary with tuple(segment_start, segment_end, valid_bases_in_segment) for keys and list(divergent_sites) for values
"""
ch = str(chromosome)
div_dict = {}
with gz.open('{al}Compara.6_primates_EPO.chr{c}_1.emf.gz'.format(al=pd.align, c=ch), 'rb') as f:
# key to the header fields:
# header_flag chromosome segment_start segment_end quality_flag chromosome_info
# SEQ homo_sapiens 1 14163 24841 1 (chr_length=249250621)
# flags, containers, counters and indices:
species = []
starts = []
ends = []
mismatch = []
valid = 0
pos = -1
hom = None
mac = None
species_data = False # a flag signalling that the lines we are viewing are alignment columns
for line in f:
if 'SEQ' in line: # 'SEQ' signifies a segment info field
assert species_data is False
line = line.split()
if line[2] == ch and line[5] == '1': # make sure that the alignment is to the desired chromosome in humans quality_flag is '1'
species += [line[1]] # collect each species in the header
starts += [int(line[3])] # collect starts and ends
ends += [int(line[4])]
if 'DATA' in line and {'homo_sapiens', 'macaca_mulatta'}.issubset(species):
species_data = True
# get the indices to scan in data columns:
hom = species.index('homo_sapiens')
mac = species.index('macaca_mulatta')
pos = starts[hom] # first homo_sapiens positional coordinate
continue
if species_data and '//' not in line:
assert pos > 0
# record the relevant bases:
human = line[hom]
macaque = line[mac]
if {human, macaque}.issubset(bases):
valid += 1
if human != macaque and {human, macaque}.issubset(bases):
mismatch += [pos]
pos += 1
elif species_data and '//' in line: # '//' signifies segment boundary
# store segment results if a boundary has been reached and data has been collected for the last segment:
div_dict[(starts[hom], ends[hom], valid)] = mismatch
# reset flags, containers, counters and indices
species = []
starts = []
ends = []
mismatch = []
valid = 0
pos = -1
hom = None
mac = None
species_data = False
elif not species_data and '//' in line:
# reset flags, containers, counters and indices
species = []
starts = []
ends = []
pos = -1
hom = None
mac = None
return div_dict
ACGT
加载整个文件只需不到一秒钟的时间,尽管它创建了一个相当复杂的字符串。(原则上,我假设我可以使用正则表达式来解析至少一些数据,例如头信息,但我不确定如果没有某种批量方法来处理每个段中的每个数据列,这是否一定会提高性能)。
最佳答案
是的,您可以使用一些正则表达式一次性提取数据;这可能是工作/性能的最佳比率。
如果您需要更多的性能,可以使用mx.TextTools来构建一个有限状态机;我很有信心这将大大加快速度,但编写规则和学习曲线所需的努力可能会使您气馁。
您还可以将数据分成块并并行处理,这可能会有所帮助。
关于python - 超越循环:高性能,大格式的数据文件解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31630260/
如果我有一个基类和两个派生类,我想手工实现两个派生类之间的转换,有什么办法吗? (在 C# 中) abstract class AbsBase { private int A; priva
非常基本的场景: 我的 Nib 上有一个 NSTableView,有一个指向它的 socket 。我的应用程序委托(delegate)中有以下内容: - (void)applicationDidFin
我正在尝试使用 R 来估计具有手动规范的多项 logit 模型。我找到了一些可以让您估计 MNL 模型的软件包 here或 here . 我发现了一些关于“滚动”你自己的 MLE 函数的其他著作 he
我正在监视某些 FreeIPA 服务器,这些服务器通常 fork 300 覆盖我专门为同样继承“Template OS Linux”和“Template IPA Servers”的此类服务器创建的另一
我正在尝试分析文本,但我的 Mac 的 RAM 只有 8 GB,并且 RidgeRegressor 在一段时间后停止,并显示 Killed: 9。我认为这是因为它需要更多内存。 有没有办法禁用堆栈大小
我有一个名为 sourceTable 的数据表,其中包含 source_Id、title 和 programme_Id 列。第二个数据表是 credits,包含 credit_Id、programme
这或多或少是一个以框架为中心的版本 past Stack Overflow question ,这是关于 MVC 应用程序的大多数介绍性 Material 如何倾向于呈现模型、 View 和 Cont
从 Java 转向 Python,有人告诉我工厂不是 Pythonic。因此,我正在寻找 a Python 方法来执行如下操作。 (我过度简化了我的目标,这样我就不必描述我的整个程序,这非常复杂)。
当 UIButton 的框架位于其父框架之外时,UIButton(或任何其他控件)是否有可能接收触摸事件?因为当我尝试这个时,我的 UIButton 似乎无法接收任何事件。我该如何解决这个问题? 最佳
我以 VBto 为起点,并大量学习了 Delphi 6 User's Guide。我可以编译我的新组件,但我想不出办法让它显示,所以我可以完成调试。 50 年的编程经验也无济于事。这是我的组件的内容:
对于以下代码,我得到的平均计算时间为 50 毫秒。我该如何优化 filter(u -> myStrings.contains(u.getName()) 获得更快的计算时间? list size 300