2010-09-27 66 views
6

Tôi có định dạng tệp (định dạng fastq) mã hóa chuỗi số nguyên dưới dạng chuỗi trong đó mỗi số nguyên được biểu thị bằng mã ascii có bù. Thật không may, có hai mã hóa trong sử dụng phổ biến, một với một bù đắp của 33 và khác với một bù đắp của 64. Tôi thường có một số 100 triệu dây dài 80-150 để chuyển đổi từ một trong những bù đắp khác. Mã đơn giản nhất mà tôi có thể đưa ra để thực hiện loại việc này là:Chuyển đổi mã ascii thành int và ngược lại trong python (nhanh)

def phred64ToStdqual(qualin): 
    return(''.join([chr(ord(x)-31) for x in qualin])) 

Điều này chỉ hoạt động tốt, nhưng không quá nhanh. Đối với 1 triệu dây, nó mất khoảng 4 giây trên máy tính của tôi. Nếu tôi thay đổi để sử dụng một vài dicts để làm bản dịch, tôi có thể nhận được điều này xuống khoảng 2 giây.

ctoi = {} 
itoc = {} 
for i in xrange(127): 
    itoc[i]=chr(i) 
    ctoi[chr(i)]=i 

def phred64ToStdqual2(qualin): 
    return(''.join([itoc[ctoi[x]-31] for x in qualin])) 

Nếu tôi chạy một cách mù quáng dưới cython, tôi sẽ giảm xuống dưới 1 giây.
Nó có vẻ như ở cấp độ C, đây chỉ đơn giản là một diễn viên để int, trừ, và sau đó đúc thành char. Tôi đã không viết nó lên, nhưng tôi đoán nó khá nhanh hơn một chút. Bất kỳ gợi ý bao gồm làm thế nào để mã tốt hơn một điều này trong python hoặc thậm chí là một phiên bản cython để làm điều này sẽ khá hữu ích.

Cảm ơn,

Sean

+0

Hãy thử thay thế '[]' với '() 'để sử dụng máy phát điện hơn là tạo và loại bỏ danh sách. Tôi nghi ngờ nó sẽ tạo ra sự khác biệt lớn, nhưng nó sẽ làm cho một số. – RichieHindle

+0

Re thay thế [] bằng(),() là dư thừa với bất kỳ python gần đây – pixelbeat

+0

Ý tưởng tốt, nhưng chuỗi tham gia cần một danh sách, tôi tin rằng, do đó sẽ không làm việc trực tiếp tôi không nghĩ. – seandavi

Trả lời

4

Nếu bạn nhìn vào các mã cho urllib.quote, có cái gì đó tương tự như những gì bạn đang làm. Dường như:

_map = {} 
def phred64ToStdqual2(qualin): 
    if not _map: 
     for i in range(31, 127): 
      _map[chr(i)] = chr(i - 31) 
    return ''.join(map(_map.__getitem__, qualin)) 

Lưu ý rằng các chức năng trên hoạt động trong trường hợp ánh xạ là không cùng độ dài (trong urllib.quote, bạn phải mất '%' -> '% 25'

. nhưng trên thực tế, vì mỗi dịch là chiều dài tương tự, trăn có một chức năng mà chỉ này rất nhanh chóng:. maketranstranslate Bạn có thể sẽ không nhận được nhanh hơn nhiều so:

import string 
_trans = None 
def phred64ToStdqual4(qualin): 
    global _trans 
    if not _trans: 
     _trans = string.maketrans(''.join(chr(i) for i in range(31, 127)), ''.join(chr(i) for i in range(127 - 31))) 
    return qualin.translate(_trans) 
+0

Cảm ơn, Mike. Đó là tốc độ cực nhanh 0,1 giây trên cùng một máy như trên và sẽ đủ nhanh cho mục đích của tôi. Tôi sẽ gắn bó với phred64ToStdqual4() như được liệt kê ở trên .... – seandavi

Các vấn đề liên quan