2016-06-05 4 views
1

Моя задача подсчитывает количество уникальных значений во втором столбце, которое соответствует каждому уникальному значению в первом столбце. Например, если у меня есть:Подсчет уникальных строк в каждой группе после группы с помощью read_csv с куском

A B 
1 a 
1 a 
1 b 
2 a 
2 a 
2 a 

Я хочу, чтобы коснуться, как это:

{1: 2, 2: 1} 

Но у меня есть огромный файл CSV и cannt прочитать его целиком. Итак, я использую chunksize. Как я могу это сделать в цикле?

+1

Насколько велика ваш файл, на диске, и вы можете исправить выход в соответствии с примерами ... Какой код вы пробовали? – Merlin

+1

Пожалуйста, объясните вашу проблему больше. Я не понимаю, откуда этот результат. –

+0

sory, я исправил свой вопрос – OleksandraK

ответ

0

я бы попытаться сделать это следующим образом:

df = pd.DataFrame() 
chunksize = 10**5 

for t in pd.read_csv(filename, usecols=['A','B'], chunksize=chunksize): 
    df = pd.concat([df, t.drop_duplicates()], ignore_index=True).drop_duplicates() 

print(df.groupby(['A'])['B'].nunique()) 

или если вам нужен словарь:

print(df.groupby(['A'])['B'].nunique().to_dict()) 

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

PPS если ваш полученный дедуплицированы DF не помещается в памяти , то я бы порекомендовал вам взглянуть на проект Apache Spark SQL, где вы можете обрабатывать свои кадры данных в кластере распределенным образом.

+0

/@ MaxU. OP все еще не указал размер файла ... Все думают, что их файлы большие и специальные. Они могут привести к перерыву в будущем коде, используя приведенный выше пример. – Merlin

+0

@Merlin, я расширил свой ответ ... Чтение CSV в кусках может помочь, если OP имеет много дубликатов – MaxU

+0

@Merlin, дело в том, что удаление дубликатов не приведет к изменению набора результатов, поскольку OP хочет подсчитать значения __unique__, но это может уменьшить потребление памяти _dramatically_, если есть много дубликатов – MaxU

0

Вы можете сделать это с Словаре по умолчанию следующим образом:

from collections import defaultdict 
col_d = defaultdict(list) 
with open('myfile', 'r') as infile: 
    for line in infile: 
      if 'A' in line or 'B' in line: 
       continue 
      line = line.strip().split(' ') 
      if len(col_d) == 0: 
       col_d[line[0]].append(line[1]) 
      elif line[1] in col_d[line[0]]: 
       pass 
      else: 
       col_d[line[0]].append(line[1]) 

for key, value in col_d.items(): 
    print '{0}\t{1}'.format(key, len(value)) 
0

Если количество уникальных значений в B не так велика вы могли бы работать с defaultdict и установить, какой будет выглядеть как-то так:

from collections import defaultdict 
dict = defaultdict(set) 
with open('file', 'r') as f: 
    for line in f: 
     line = line.strip().split(' ') 
     col_d[line[0]].add(line[1]) 
for key in dict: 
    dict[key]= len(dict[key])