2016-04-20 3 views
2

У меня есть очень большой файл, который имеет два столбца и является ~ 10GB в размере:Построение карты для больших наборов данных

A B 
1 2 
3 7 
1 5 
6 5 
9 8 

По сути, я хочу, чтобы создать карту, как структура из этого файла выглядит следующим образом:

{{1 -> 2,5},{3->7}, {6->5}, {9->8}} 

Целью является написать функцию, которая вычисляет процент уникальных значений, на которые влияет удаление ключа. Например, в приведенном выше примере, если я удалю ключ, это повлияет на 1, 2/4 значений. Если я удаляю как 1, так и 6, это влияет на 2/4. Проблема в том, что эта структура карты будет использовать слишком много памяти. Существуют ли более эффективные альтернативные подходы? Я думаю, вам понадобится карта, чтобы отслеживать дубликаты. Вам нужно знать, какие ключи уже были удалены, чтобы вы не удваивали счет. Вот мой исходный код:

with open("C:/Users/XX/Desktop/Train.tsv") as f: 
    counter = 0 
    for line in f: 
     #split line into key and value 
     #add key into set 
     #if set does not contain key 
     #create new key 
     #add list for this key 
     #append value to this list 
     #else 
     #append value to already existing list for that key 

Это сообщение об ошибке я получаю после запуска кода Александра: не уверен, что KeyError 293 означает

--------------------------------------------------------------------------- 
KeyError         Traceback (most recent call last) 
<ipython-input-22-73145e080824> in <module>() 
     7  for line in f: 
     8   key, value = line.split() 
----> 9   if value not in dd[key]: 
    10    dd[key].append(value) 
    11   counter = counter+1 

KeyError: '293' 
+0

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

+0

Каковы фактические диапазоны двух столбцов? Гарантируются ли они целыми числами? Маленькие целые числа? Персонажи? –

+0

Типы обоих должны быть целыми числами. Кроме того, если я не знаю точных значений и знаю только частоты для каждого ключа, было бы трудно получить покрытие, так как я бы стал двойным подсчетом, так как для разных ключей можно было иметь одинаковые значения. – zorny

ответ

2

Что-то вроде этого?

#!python3 

from collections import defaultdict 

AB_map = defaultdict(set) 
Values = set() 

with open('train.tsv') as infile: 
    headers = next(infile) 
    for line in infile: 
     if not line.strip(): 
      continue 
     a,b = map(int, line.split()) 
     AB_map[a].add(b) 
     Values.add(b) 

print("# of keys:", len(AB_map.keys())) 
print("# of values:", len(Values)) 

def impact_of_deletion(keylist): 
    values_impacted = set([]) 
    for key in keylist: 
     values_impacted.update(AB_map[key]) 
    return values_impacted 

for hyp in ((1,), (1,6)): 
    print("Deleting", hyp, "would impact:", len(impact_of_deletion(hyp))) 
1

Вы можете использовать defaultdict для этого, который мы установим в автоматически присваивать каждой группе пустой список:

from collections import defaultdict 

filename = "C:/Users/XX/Desktop/Train.tsv" 
dd = defaultdict(list) 
with open(filename) as f: 
    for line in f: 
     key, value = line.split(',') # Assuming comma delimited. 
     if value not in dd[key]: # If you only want to retain unique values. 
      dd[key].append(value) 
+0

Это не очень помогает в проблемах с памятью. – user2357112

+0

Он должен. Прежде всего вы читаете файл строки за строкой, а не навалом. Во-вторых, вы сохраняете уникальные значения для каждого ключа, а не все из них. Существует не так много другого, что можно было бы сделать без сохранения результатов в базу данных или файл. – Alexander

+0

@ Alexandr @zorny Я думаю, что это должно быть скорее 'dd = defaultdict (list)'. Думаю, это решает проблему KeyError. – ptrj

Смежные вопросы