我需要从一个熊猫序列(从下面的数据框中的“ amino_acid”列中)制作一个频率字典,该字典还为字典中的每个条目(从“ templates”列中)添加一个相邻行。
templates amino_acid
0 118 CAWSVGQYSNQPQHF
1 635 CASSLRGNQPQHF
2 468 CASSHGTAYEQYF
3 239 CASSLDRLSSGEQYF
4 51 CSVEDGPRGTQYF
根据this post,我当前遍历数据帧的方法似乎效率低下,甚至是一种反模式。如何提高效率/使用最佳实践来做到这一点?
我目前的做法:
sequence_counts = {}
seqs = list(zip(df.amino_acid, df.templates))
for seq in seqs:
if seq[0] not in sequence_counts:
sequence_counts[seq[0]] = 0
sequence_counts[seq[0]] += seq[1]
我已经按照以下方式看到了人们,但无法弄清楚如何对其进行调整以添加每个相应的“模板”条目:
sequence_counts = df['amino_acid'].value_counts().to_dict()
任何帮助/反馈将不胜感激! :)
答案 0 :(得分:0)
只需测试@Nolan Conaway注释的代码,这是最好的做法:
df.groupby('amino_acid').templates.sum()
在此之后,您将获得一个包含所需内容的数据框,并且由于它使用了所有数据框本机函数,因此运行速度更快,并且当然更加简洁,简短和简洁。
为了提高速度,我在10 ^ 4数据帧中测量了经过时间,该代码比下面的答案快三个数量级(0.007 vs 4.3秒)。
诺兰(Nolan)应该在评论中加上一个注释,这样他才能以对熊猫数据框api的巧妙巧妙使用而受到赞誉。
我会在这里留下我的答案,以防万一有人觉得这些评论有用。
我不完全了解pandas api,但是找不到能满足您需求的api组合(但Nolan做到了!)。但是,似乎可以通过不创建列表或显式压缩数据来极大地改善代码。如果使用迭代器代替这些结构,则可以提高性能。
例如,在list(zip(df.amino_acid, df.templates))
中,list
并不是必需的,因为zip
已经返回了一个列表。此外,您可以使用itertools库的izip
函数,该函数可以提供迭代器而无需构建列表。另外,最好使用pandas迭代器构造函数而不是调用列(据我所知,它还将返回列表中的数据副本,因此在数据帧上还有另一个迭代)。
无论如何,我会尝试这样的事情。
sequence_counts = { }
for _, row in df.iterrows():
t, aa = row['templates'], row['amino_acid']
s = sequence_counts.get(aa, 0)
sequence_counts[aa] = s + t
通过这种方式,您实际上只需要遍历数据一次,而数据帧会为您提供迭代器。
答案 1 :(得分:-1)
我对您的问题的理解是,您希望创建一个字典键/值,使key=amino_acid
和value is the frequency = templates
自从您成功创建带有seqs = list(zip(df.amino_acid, df.templates))
的元组
您的字典可以构造为:
sequence_counts = dict(seqs)
一行:
sequence_counts = dict(zip(df.amino_acid, df.templates))
或者您可以通过这种方式做些事情:
sequence_counts = dict([(k,v) for k,v in zip(df.amino_acid,df.templates)])