Python 从无循环的数据帧构建频率字典

Python 从无循环的数据帧构建频率字典,python,python-3.x,pandas,dataframe,bioinformatics,Python,Python 3.x,Pandas,Dataframe,Bioinformatics,我需要从pandas系列(从下面的dataframe中的'amino_acid'列)中创建一个频率字典,它还为字典中的每个条目(从'templates'列)添加一个相邻的行 我目前在数据帧中进行迭代的方法似乎效率低下,甚至是一种反模式。我如何提高效率/使用最佳实践来完成这项工作 我目前的做法是: sequence_counts={} seqs=列表(zip(氨基酸测序模板)) 对于seq中的seq: 如果seq[0]不在顺序中_计数: 序列计数[序列[0]]=0 序列计数[seq[0]+=seq

我需要从pandas系列(从下面的dataframe中的'amino_acid'列)中创建一个频率字典,它还为字典中的每个条目(从'templates'列)添加一个相邻的行

我目前在数据帧中进行迭代的方法似乎效率低下,甚至是一种反模式。我如何提高效率/使用最佳实践来完成这项工作

我目前的做法是:

sequence_counts={}
seqs=列表(zip(氨基酸测序模板))
对于seq中的seq:
如果seq[0]不在顺序中_计数:
序列计数[序列[0]]=0
序列计数[seq[0]+=seq[1]
我见过下面的人,但不知道如何调整它来添加每个相应的“模板”条目:

sequence_counts=df['aminomy_acid'].value_counts().to_dict()

任何帮助/反馈都将不胜感激!:)

根据您的问题,我的理解是您希望创建一个字典键/值,以便
key=aminoum_acid
value是频率=模板

因为您已经成功地创建了带有
seqs=list(zip(df.aminomy\u 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)])

刚刚测试了@Nolan Conaway comment的代码,这是最好的做法:

df.groupby('amino_acid').templates.sum()
这样,您就得到了一个包含所需内容的数据帧,而且由于它使用了所有的数据帧本机函数,因此运行速度更快,当然也更简洁、简短和干净

对于速度,我在10^4数据帧中测量了经过的时间,这段代码比下面的答案快了大约三个数量级(0.007 vs 4.3秒)

Nolan应该把评论放在一个答案中,这样他就可以通过巧妙地使用pandas dataframe api来获得信任

我将在这里留下我的答案,以防有人认为这些评论有用

我不完全了解pandas api,但我找不到任何api组合可以满足您的需要(但Nolan做到了!)。但通过不创建列表或显式地对数据进行ziping,似乎可以大大改进代码。如果使用迭代器而不是那些结构,则可以提高性能

例如,在
list(zip(df.aminomic\u acid,df.templates))
中,实际上并不需要
list
,因为
zip
已经返回了一个列表。此外,您还可以使用itertools库的
izip
函数,该函数提供了一个迭代器,而无需构建列表。此外,最好使用迭代器构造函数,而不是调用列(据我所知,它还将返回列表中的数据副本,因此您在dataframe上还有另一个迭代)

不管怎样,我会试试这样的

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

通过这种方式,您只需使用dataframe提供的迭代器对数据进行一次迭代。

听起来您想按聚合进行分组,这就是您想要的吗
df.groupby('氨基酸').templates.sum()
。如果没有,您能澄清一些示例输出是什么样子吗?是的,谢谢@NolanConaway!这正是我想要的。我需要得到每个氨基酸字符串的频率加上每次出现的模板条目的总和。问题中的代码显示他需要相同氨基酸的模板总和。此外,在dict构造函数中创建列表也不是真正必要的,并且会导致最差的性能。
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