【问题标题】:How do I count the occurences of characters of a partition in python?如何计算python中分区字符的出现次数?
【发布时间】:2015-05-03 15:31:39
【问题描述】:

我有一个包含序列的大文件;我只想分析最后一组字符,它们恰好是可变长度的。在每一行中,我想获取文本文件中每个集合的第一个字符和最后一个字符,并计算这些字符的总实例数。

以下是文件中数据的示例:

-1iqd_BA_0_CDRH3.pdb kabat H3 PDPDAFDV

-1iqw_HL_0_CDRH3.pdb kabat H3 NRDYSNNWYFDV

我想取“H3”之后的第一个字符和最后一个字符(在示例中都是粗体)。 这两行的输出应该是:

第一个计数器({'N': 1, 'P': 1})

最后一个计数器({'V': 2})

这是我到目前为止所做的:

f = open("C:/CDRH3.txt", "r")
from collections import Counter
grab = 1
for line in f:
   line=line.rstrip()
   left,sep,right=line.partition(" H3 ")
   if sep:
         AminoAcidsFirst = right[:grab] 
         AminoAcidsLast = right[-grab:]
print ("first ",Counter(line[:] for line in AminoAcidsFirst))
print ("last ",Counter(line[:] for line in AminoAcidsLast))
f.close()

这仅打印最后一行数据的计数,如下所示:

first Counter({'N': 1})
last Counter({'V': 1})

如何计算文件所有行中的所有这些字符? 笔记: 打印 (AminoAcidsFirst) 或 (AminoAcidsLast) 给出了所有垂直行的所需列表,但我无法对其进行计数或将其输出到文件中。写入新文件只会写入原始文件最后一行的字符。 谢谢!

【问题讨论】:

  • 您是否需要将第一个字符和最后一个字符的计数分开,或者它们可以在同一个计数器中?

标签: python list counter partition


【解决方案1】:

无需计数器:只需抓取spliting 之后的最后一个令牌并计算第一个和最后一个字符:

first_counter = {}
last_counter = {}
for line in f:
   line=line.split()[-1]   # grab the last token
   first_counter[line[0]] = first_counter.get(line[0], 0) + 1
   last_counter[line[-1]] = last_counter.get(line[-1], 0) + 1    

print("first ", first_counter)
print("last ", last_counter)

输出

first  {'P': 1, 'N': 1}
last  {'V': 2}

【讨论】:

  • 这返回了一个错误:Line 4, in 0. builtins.IndexError: list index out of range。使用 Py3。更改了 print() 格式。我不确定是否还缺少其他东西。不过还是谢谢。
  • @BioEng-Mike 是的,print 已从内置函数移至 Python3 中的函数(因此您需要添加括号)。我会更新答案。
【解决方案2】:

创建 2 个空列表并像这样在每个循环中追加:

f = open("C:/CDRH3.txt", "r")
from collections import Counter
grab = 1
AminoAcidsFirst = []
AminoAcidsLast = []
for line in f:
   line=line.rstrip()
   left,sep,right=line.partition(" H3 ")
   if sep:
         AminoAcidsFirst.append(right[:grab])
         AminoAcidsLast.append(right[-grab:])
print ("first ",Counter(line[:] for line in AminoAcidsFirst))
print ("last ",Counter(line[:] for line in AminoAcidsLast))
f.close()

这里:

  1. 空列表的创建:

    AminoAcidsFirst = [] AminoAcidsLast = []

  2. 在每个循环中追加:

    AminoAcidsFirst.append(right[:grab]) AminoAcidsLast.append(right[-grab:])

【讨论】:

  • 这对我使用 Py3 非常有效,并且我能够输出到文件。非常感谢!
【解决方案3】:

我想指出两件重要的事情

  1. 永远不要透露您计算机上的文件路径,如果您来自科学界,这尤其适用

  2. 使用with...as 方法,您的代码可以更加pythonic

现在是程序

from collections import Counter

filePath = "C:/CDRH3.txt"
AminoAcidsFirst, AminoAcidsLast = [], [] # important! these should be lists

with open(filePath, 'rt') as f:  # rt not r. Explicit is better than implicit
    for line in f:
        line = line.rstrip()
        left, sep, right = line.partition(" H3 ")
        if sep:
            AminoAcidsFirst.append( right[0] ) # really no need of extra grab=1 variable
            AminoAcidsLast.append( right[-1] ) # better than right[-grab:]
print ("first ",Counter(AminoAcidsFirst))
print ("last ",Counter(AminoAcidsLast))

不要使用line.strip()[-1],因为sep 验证很重要

输出

first  {'P': 1, 'N': 1}
last  {'V': 2}

注意:数据文件可能会变得非常大,您可能会遇到内存问题或计算机死机。那么,我可以建议懒惰阅读吗?以下是更健壮的程序

from collections import Counter

filePath = "C:/CDRH3.txt"
AminoAcidsFirst, AminoAcidsLast = [], [] # important! these should be lists

def chunk_read(fileObj, linesCount = 100):
    lines = fileObj.readlines(linesCount)
    yield lines

with open(filePath, 'rt') as f:  # rt not r. Explicit is better than implicit
    for aChunk in chunk_read(f):
        for line in aChunk:
            line = line.rstrip()
            left, sep, right = line.partition(" H3 ")
            if sep:
                AminoAcidsFirst.append( right[0] ) # really no need of extra grab=1 variable
                AminoAcidsLast.append( right[-1] ) # better than right[-grab:]
print ("first ",Counter(AminoAcidsFirst))
print ("last ",Counter(AminoAcidsLast))

【讨论】:

  • 感谢您提供有关不透露文件位置的提示。第一组代码对我的目的来说工作得很好。一旦我将“linesCount”调整为等于文件中的总字符数,第二个文件就起作用了。我正在查看大小约为 36 kb、最多 1000 行的文件,因此第一个版本就足够了。谢谢!非常感谢。
【解决方案4】:

如果您将语句放在 for 循环的 底部 或之后以打印 AminoAcidsFirstAminoAcidsLast,您将看到在每次迭代中您只是分配了一个新值。您的意图应该是收集、包含或累积这些值,然后再将它们提供给 collections.Counter

s = ['-1iqd_BA_0_CDRH3.pdb kabat H3 PDPDAFDV', '-1iqw_HL_0_CDRH3.pdb kabat H3 NRDYSNNWYFDV']

立即解决您的代码的方法是累积字符:

grab = 1
AminoAcidsFirst = ''
AminoAcidsLast = ''
for line in s:
   line=line.rstrip()
   left,sep,right=line.partition(" H3 ")
   if sep:
         AminoAcidsFirst += right[:grab] 
         AminoAcidsLast += right[-grab:]
print ("first ",collections.Counter(AminoAcidsFirst))
print ("last ",collections.Counter(AminoAcidsLast))

另一种方法是按需生成字符。定义一个生成器函数,它将产生你想要计算的东西

def f(iterable):
    for thing in iterable:
        left, sep, right = thing.partition(' H3 ')
        if sep:
            yield right[0]
            yield right[-1]

然后将其提供给collections.Counter

z = collections.Counter(f(s))

或者使用文件作为数据源:

with open('myfile.txt') as f1:
    # lines is a generator expression
    # that produces stripped lines
    lines = (line.strip() for line in f1)
    z = collections.Counter(f(lines))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    相关资源
    最近更新 更多