【问题标题】:Regrouping a list positionally into quantiles将列表按位置重新分组为分位数
【发布时间】:2018-11-09 18:19:36
【问题描述】:

我有一个字典,其中每个键对应一个基因名称,每个值对应一个列表。每个基因的列表长度不同,因为每个元素代表不同的核苷酸。每个位置的数字表示核苷酸的“分数”。

由于每个基因的长度不同,我希望能够通过将每个基因分成分位数(最有可能是百分位数:100 个 bin)来直接比较它们的位置分数分布。

这是一些模拟数据:

myData = {
'Gene1': [3, 1, 1, 2, 3, 1, 1, 1, 3, 0, 0, 0, 3, 3, 3, 0, 1, 2, 1, 3, 2, 2, 0, 2, 0, 1, 0, 3, 0, 3, 1, 1, 0, 3, 0, 0, 1, 0, 1, 0, 1, 3, 3, 2, 3, 1, 0, 1, 2, 2, 0, 3, 0, 2, 0, 1, 1, 2, 3, 3, 1, 2, 1, 3, 1, 0, 0, 3, 2, 0, 3, 0, 2, 1, 1, 1, 2, 1, 1, 3, 0, 1, 1, 1, 3, 3, 0, 2, 2, 1, 3, 2, 3, 0, 2, 3, 2, 1, 3, 1, 3, 2, 1, 3, 0, 3, 3, 0, 0, 1, 0, 3, 1, 1, 3, 0, 0, 2, 3, 1, 0, 2, 1, 2, 1, 2, 1, 2, 0, 1, 1, 1, 3, 1, 3, 1, 3, 2, 3, 3, 3, 1, 1, 2, 1, 0, 2, 2, 2, 0, 1, 0, 3, 1, 3, 2, 1, 3, 0, 1, 3, 1, 0, 1, 2, 1, 2, 2, 3, 2, 3, 2, 2, 2, 1, 2, 2, 0, 3, 1, 2, 1, 1, 3, 2, 2, 1, 3, 1, 0, 1, 3, 2, 2, 3, 0, 0, 1, 0, 0, 3],
'Gene2': [3, 0, 0, 0, 3, 3, 1, 3, 3, 1, 0, 0, 1, 0, 1, 1, 3, 2, 2, 2, 0, 1, 3, 2, 1, 3, 1, 1, 2, 3, 0, 2, 0, 2, 1, 3, 3, 3, 1, 2, 3, 2, 3, 1, 3, 0, 1, 1, 1, 1, 3, 2, 0, 3, 0, 1, 1, 2, 3, 0, 2, 1, 3, 3, 0, 3, 2, 1, 1, 2, 0, 0, 1, 3, 3, 2, 2, 3, 1, 2, 1, 1, 0, 0, 1, 0, 3, 2, 3, 0, 2, 0, 2, 0, 2, 3, 0, 3, 0, 3, 2, 2, 0, 2, 3, 0, 2, 2, 3, 0, 3, 1, 2, 3, 0, 1, 0, 2, 3, 1, 3, 1, 2, 3, 1, 1, 0, 1, 3, 0, 2, 3, 3, 3, 3, 0, 1, 2, 2, 2, 3, 0, 3, 1, 0, 2, 3, 1, 0, 1, 1, 0, 3, 3, 1, 2, 1, 2, 3, 2, 3, 1, 2, 0, 2, 3, 1, 2, 3, 2, 1, 2, 2, 0, 0, 0, 0, 2, 0, 2, 3, 0, 2, 0, 0, 2, 0, 3, 3, 0, 1, 2, 3, 1, 3, 3, 1, 2, 1, 2, 1, 3, 2, 0, 2, 3, 0, 0, 0, 1, 1, 0, 1, 2, 0, 1, 2, 1, 3, 3, 0, 2, 2, 1, 0, 1, 1, 1, 0, 0, 2, 1, 2, 0, 1, 2, 1, 1, 3, 0, 1, 0, 1, 2, 1, 3, 0, 2, 3, 1, 2, 0, 0, 3, 2, 0, 3, 2, 1, 2, 3, 1, 0, 1, 0, 0, 1, 2, 3, 3, 2, 2, 1, 2, 2, 3, 3, 3, 3, 0, 0, 2, 2, 2, 2, 3, 2, 3, 2, 0, 3, 1, 0, 2, 3, 0, 1, 2, 2, 0, 2],
'Gene3': [2, 3, 1, 0, 3, 2, 1, 0, 1, 2, 1, 2, 1, 3, 0, 2, 2, 3, 2, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 2, 2, 1, 3, 1, 2, 3, 0, 0, 3, 1, 0, 3, 2, 2, 3, 0, 0, 3, 3, 1, 1, 1, 0, 0, 2, 3, 2, 0, 2, 0, 1, 0, 2, 3, 0, 2, 0, 3, 3, 0, 0, 1, 0, 3, 2, 1, 1, 3, 3, 0, 2, 3, 1, 1, 0, 1, 3, 2, 1, 0, 3, 2, 0, 3, 2, 1, 1, 0, 3, 0, 0, 2, 0, 3, 3, 0, 2, 0, 3, 3, 2, 0, 0, 2, 2, 0, 2, 0, 0, 2, 3, 3, 3, 3, 1, 3, 0, 0, 3, 1, 0, 2, 2, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 3, 0, 0, 3, 0, 2, 2, 0, 0, 3, 0, 1, 3, 1, 1, 0, 2, 2, 3, 3, 0, 2, 0, 0, 2, 3, 1, 2, 1, 1, 2, 2, 0, 0, 3, 2, 2, 2, 1, 2, 0, 3, 2, 2, 2, 2, 1, 0, 3, 2, 2, 1, 0, 0, 2, 2, 0, 3, 2, 0, 2, 2, 1, 1, 1, 2, 1, 2, 0, 1, 0, 3, 2, 0, 2, 3, 3, 0, 2, 2, 0, 1, 1, 3, 0, 0, 1, 2, 3, 1, 3, 2, 3, 3, 2, 0, 0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 2, 1, 3, 1, 3, 1, 1, 0, 3, 0, 1, 1, 1, 1, 1, 0, 2, 1, 2, 1, 2, 0, 2, 0, 0, 2, 2, 2, 3, 3, 0, 0, 3, 2, 1, 2, 1, 0, 3, 2, 3, 1, 1, 0, 1, 3, 2, 0, 3, 1, 3, 1, 2, 0, 0, 2, 3, 2, 2, 0, 3, 0, 2, 2, 2, 3, 3, 2, 1, 3, 3, 0, 2, 2, 2, 1, 1, 2, 1, 3, 2, 3, 2, 1, 3, 1, 0, 0, 2, 0, 1, 1, 3, 3, 0, 1, 2, 3, 1, 2, 3, 1, 1, 1, 2, 0, 2, 0, 1, 0, 3, 1, 0, 3, 3, 1, 3, 1, 1, 2, 2, 0, 2, 0, 1, 0, 3, 1, 1, 1, 3, 3, 0, 0, 1, 1, 2, 3, 0, 2, 0, 1, 1, 3, 3, 1, 1, 0, 0, 2, 0, 1, 2, 2, 2, 3, 1, 1, 1, 0, 3, 0, 0, 0, 1, 0, 1, 3, 1, 2, 2, 1, 2, 2]
}

如您所见,Gene1 的长度为 201,Gene2 的长度为 301。但是,Gene3 的长度为 428。我想总结这些列表中的每一个,以便对于任意数量的 bin ( nBins),我可以将列表划分为列表列表。

例如,对于前两个基因,如果我选择 nBins=100,那么 Gene1 看起来像 [[3,1],[1,2],[3,1],[1,1]...],而 Gene2 看起来像 [[3,0,0],[0,3,3],[1,3,3]...]。也就是说,我想根据 positions 而不是值本身进行分区。我的数据集很大,所以我正在寻找一个可以最有效地做到这一点的库。

【问题讨论】:

  • 对于nBins = 100,您将如何对myData['Gene3'] 进行分组?你假设len(myData['key']) % nBins
  • 诸如“我正在寻找图书馆”之类的请求对于本网站来说是明确的题外话。如果你编辑你的问题以有效地完成你的目标,并且你表现出你自己的一些努力,你可能会得到很好的答案。

标签: python python-3.x


【解决方案1】:

您不需要图书馆。纯 python 在 90% 的情况下应该足够快:

nBins = 100

def group(l, size):
    return [l[i:i + size] for i in range(0, len(l) + len(l) % size, size)]


bin_data = {k: group(l, len(l) // nBins ) for k, l in myData.items()}
print(bin_data)

【讨论】:

  • len(l) + len(l) 不是比2 * len(l) 更好吗?
  • 哦!忘掉它。我没有考虑运算符的优先级。
  • 谢谢!你说得对,这对于我规模上的数据来说已经足够快了。我在通过这种方法生成的样本数据上再次对其进行了测试,它仍然非常快速地计算了分组(约 12 秒)。 import random; myData = { 'Gene{}'.format(i) : [random.randint(0,4) for j in range(5000)] for i in range(20000) }
【解决方案2】:

你确定Gene1的长度不是201吗?

在长度不能被箱数整除的情况下,您不会说出您想要发生的事情。我的代码混合了长度 floor(length/nBins) 和 ceiling(length/nBins) 的子列表,以获得正确的 bin 数量。

new_data = {key : [value[
           int(bin_number*len(value)/nBins):
           int((bin_number+1)*len(value)/nBins)
                ]
            for bin_number in range(nBins)] for key, value in myData.items()}

【讨论】:

  • 是的,我犯了一个错误。长度分别为 201、301 和 428。这个想法是为了说明每个基因都有随机数量的元素,这些元素可能无法整除。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
  • 1970-01-01
  • 2020-05-11
  • 2022-10-16
  • 2016-01-15
  • 2021-08-28
  • 1970-01-01
相关资源
最近更新 更多