我有一个名为“data”的结构化数组,对同一个条目有几个分数。为了这个问题,我将“数据”减少到以下2列。
queryid bitscore gene1 500 gene1 480 gene1 440 gene2 900 gene2 300
我想要做的是为queryid提取相同的最高值,即bitscore比最高位核低至少10%的任何公共条目。
例如,只有前两个条目“gene1”应该保守,因为第三个条目的位数低于500的10%。对于基因2,只应保留第一个(这一个很容易)。
queryid bitscore gene1 500 gene1 480 gene2 900
当我像这样做一个循环时:
for i in range(0, lastrow-1, 1):
if data[i]['queryid'] == data[i+1]['queryid']:
if data[i+1]['bitscore'] < data[i]['bitscore']-(0.01*data[i]['bitscore']):
data[i+1]['queryid'] = 'DELETE'
data = data[data[:]['queryid'] != 'DELETE']
所有“gene1”条目都将被保留,因为440在480的10%范围内。
我可以将最高价值添加到另一个可以作为参考的列,但我想检查一下你们是否对它有更好的了解......
答案 0 :(得分:3)
如果你能够使用pandas,那就会成为一个问题:
from pandas import DataFrame
import numpy as np
# Taken from Theodros
data = zip(('gene1',) * 3 + ('gene2',) * 2, [500, 480, 440, 900, 300])
dtype = [('queryid', 'S6'), ('bitscore', 'i4')]
struct_arr = np.array(data, dtype=dtype)
# Create pandas DataFrame from NumPy struct array
df = DataFrame.from_records(struct_arr)
# Filter the rows per group
df.groupby('queryid').apply(lambda x: x[x["bitscore"] >= x["bitscore"].max() * 0.9])
产地:
queryid bitscore
queryid
gene1 0 gene1 500
1 gene1 480
gene2 3 gene2 900
答案 1 :(得分:2)
使用逻辑索引可能比for
循环快得多。这样的事情怎么样:
def high_bitscores(a,qid,thresh=0.9):
valid = a[a['queryid'] == qid]
return valid[valid['bitscore'] >= valid['bitscore'].max()*thresh]
修改:如果您要返回data
中传递此条件的所有元素,您可以循环显示唯一的queryid
值data
并更新一组布尔索引,指定哪些元素通过测试:
def all_high_bitscores(a,thresh=0.9):
# set of indices for the elements in a that we're going to keep
keep = np.zeros(a.size,np.bool)
for qid in set(a['queryid']):
idx = a['queryid'] == qid
keep[idx] = a[idx]['bitscore'] >= a[idx]['bitscore'].max()*thresh
return a[keep]
答案 2 :(得分:1)
您可以使用itertools.groupby来迭代具有相同queryid
的块。然后,您可以过滤掉阈值以下的记录。在此步骤中,您将保留numpy.structured_array数据结构并处理单个元组。通过将filter
定义为生成器,您可以从过滤器输出中动态构建新的结构化数组。
from itertools import groupby
from operator import itemgetter
def filter(struct_arr, threshold):
for k, g in groupby(struct_arr, key=itemgetter(0)):
ref = g.next()
yield ref
ref = ref[1]
for e in g:
if (float(e[1]) / ref) < threshold:
break
yield e
示例:强>
data = zip(('gene_1',) * 3 + ('gene_2',) * 2, [500, 480, 440, 900, 300])
dtype = [('query_id', 'S6'), ('bitscore', 'i4')]
struct_arr = np.array(data, dtype=dtype)
np.fromiter(filter(struct_arr), dtype=dtype)
给出了
array([('gene_1', 500), ('gene_1', 480), ('gene_2', 900)],
dtype=[('query_id', 'S6'), ('bitscore', '<i4')])