2017-02-15 3 views
2

У меня есть матричная форма (600, 9 миллиардов), сохраненная как файл *.txt. Каждая строка матрицы называется другим именем выборки sample_name1, sample_name2 и т. Д. Однако существуют имена примеров, которые не стандартизированы, например. s###30023Как подсчитать символы каждой строки матрицы с помощью Python? Счетчик()?

Впоследствии имеется строка из трех символов, каждая длиной ~ 9 миллиардов символов.

sample_name1 ab2ab222baab22ba2bab2b2aab22ab22bababab2baab2b2a

Матрица в следующем формате:

600 9123001002 
sample_name1 ab2ab222baab22ba2bab2b2aab22ab22bababab2baab2b2a2bababab2baab2b2ab2a... 
sample_name2 abbbbbbbbbbbb2bbbbbbbbbbabbbbbbaaabbbbbbbbb222bbbbbabababbbb2b2b2bbb... 
... 

Я хотел бы создать словарь (или список, панды DataFrame) каждый образец с количеством уникальных персонажей подсчитанных. То есть, в словарной форме:

sample_name1 = {'a': 1824600201, 'b': 2736900300, '2': 4561500501} 

для каждой строки.

Самый быстрый способ подсчета символов в python - использовать from collections import Counter. Можно загрузить текстовый файл в numpy, перебирать каждую строку матрицы и затем использовать для каждой строки Counter().

Однако, как очистить правильную метку для каждой строки, особенно если эти метки не стандартизированы? Возможно, я мог бы взять первые X символов для каждой строки матрицы?

+0

ли вы гарантировали, что пространство отделяет ярлык от текста? – AChampion

+0

@AChampion Да, это похоже на вкладку. – ShanZhengYang

+0

@ShanZhengYang: есть ли другой символ пробела подряд? –

ответ

1

Предполагая, что достаточно небольшое количество данных, чтобы поместиться в памяти (в каждой строке), то вы могли бы сделать что-то же просто, как:

results = {} 
with open('<myfile>') as f: 
    next(f) # skip first line 
    for line in f: 
     title, code = line.strip().split(' ') 
     results[title] = Counter(code) 

Учитывая свой небольшой пример набора данных выше вы получите:

{'sample_name1': Counter({'.': 3, '2': 21, 'a': 22, 'b': 25}), 
'sample_name2': Counter({'.': 3, '2': 7, 'a': 8, 'b': 53})} 
+0

Мне непонятно, как вы читаете в большом текстовом файле ... (также, это python2.x, это нормально ... для других читателей SO это хорошо известно) – ShanZhengYang

+0

Исправлено, я использовал 'StringIO (str)', чтобы превратить строку в файловый интерфейс, для замены файла с помощью 'open (''). Почему вы считаете, что это python 2.x, моя среда по умолчанию - 3.x? – AChampion

+0

Я не думал, что 'StringIO()' существует в Python3.x – ShanZhengYang

1

Я не тестировал это с чем-то почти таким же большим, как ваши данные, но вы можете попробовать что-то вроде следующего.

Предпосылка - мы читаем каждую строку в кусках и переводим символы ascii a, b, 2 в те, из которых мы берем текущую гистограмму. Причина, по которой мы читаем каждую строку в кусках, состоит в том, что каждая строка составляет 9 миллиардов байт, то есть файл не будет помещаться в память на многих компьютерах.

Сначала давайте определим что-то. transtable - это массив, который примет символы в a,b,2 и преобразует их в 0,1,2. Я написал его таким образом, чтобы его можно было обобщить, если у вас больше символов. Сохраним результаты в словаре hists формы sample_name: np.array([a_count, b_count, 2_count]).

import numpy as np 

transtable = np.arange(256, dtype=np.uint8) 
transtable[np.frombuffer('ab2')] = np.arange(3) 

chunksize = 436549 # 9123001002/2/3^5/43 
invchunksize = 43*2*3**5 

hists = {} 
bins = np.arange(4) # 3 + 1 
# convenience function to take string buffer to counts of a,b,2 (0,1,2) 
hist_func = lambda buff: np.histogram(transtable[np.frombuffer(buff, np.uint8)], 
             bins=bins)[0] 

Теперь мы открываем файл и разобрать заголовок

with open(infile, 'r') as fin: 
    header_line = fin.readline() 
    rows, cols = map(int, header_line.split()) 

С открытия файла, давайте теперь цикл через него, первый получает имя образца

while True: 
     # parse name 
     name = '' 
     nextchar = '' 
     while nextchar != ' ': #may need to replace with '\t' 
      nextchar = fin.read(1) 
      name += nextchar 

Теперь, у нас есть имя образца, давайте проанализируем фактические данные:

 hist = np.zeros(3) 
     for _ in xrange(invchunksize): 
      dat = np.fromfile(fin, dtype=np.uint8, count=(chunksize)) 
      # stop reading if we didn't get chunksize bytes during last read 
      if data.size != chunksize: 
       break 

      hist += hist_func(dat) 

     hists[name] = hist 

     # read newline character and continue on to next line 
     fin.read(1) 
Смежные вопросы