2015-03-25 7 views
1

Я пытаюсь получить уникальные значения из имени столбца для каждого отдельного значения в столбце «пол».Получите уникальные значения из столбца, используя Python

Вот пример данные: образца input_file_data:

index,name,gender,alive 
1,Adam,Male,Y 
2,Bella,Female,N 
3,Marc,Male,Y 
1,Adam,Male,N 

я мог бы получить его, когда я даю значение, соответствующее «полу», как, например, дал «Мужчина» в коде ниже:

filtered_data = filter(lambda person: person["gender"] == "Male", input_file_data) 
reader = (dict((k, v.strip()) for k, v in row.items() if v) for row in filtered_data) 
countt = [rec[gender] for rec in reader] 
final1 = input_file_name + ".txt", "gender", "Male" 
output1 = str(final1).replace("(", "").replace(")", "").replace("'","").replace(", [{", " -- [").replace("}", "") 
final2 = set(re.findall(r"name': '(.*?)'", str(filtered_data))) 
final_count = len(final2) 
output = str(final_count) + " occurrences", str(final2) 
output2 = output1, str(output) 
output_final = str(output2).replace('\\', "").replace('"',"").replace(']"', "]").replace("set", "").replace("(", "").replace(")", "").replace("'","").replace(", [{", " -- [").replace("}", "") 
output_final = output_final + "\n" 

выходной ток:

input_file_name.txt, gender, Male, 2 occurrences, [Adam,Marc] 

Ожидаемый результат:

input_file_name.txt, gender, Male, 2 occurrences, [Adam,Marc], Female, 1 occurrences [Bella] 

, который должен отображать все уникальные вхождения имен для каждого отдельного гендерного значения (без жесткого кодирования). Также я не хочу использовать Панды. Любая помощь высоко ценится.

PS- У меня есть несколько файлов, и не все файлы имеют одинаковые столбцы. Поэтому я не могу их жестко закодировать. Кроме того, все файлы имеют столбец «name», но не все файлы имеют столбец «gender». И этот скрипт должен работать для любого другого столбца, такого как «индекс» или «живой», или что-то еще, но не только гендер.

+0

Почему вы не хотите использовать панды? он предназначен именно для такого рода вещей. у него есть немного кривая обучения, но он стоит учиться. – acushner

+0

@acushner Есть еще несколько человек, которые будут запускать этот скрипт. Они еще более новы для Python, чем я, и установка пакетов сама по себе является новой для них. Поэтому я предпочитаю придерживаться пакетов, установленных по умолчанию, если это имеет смысл. – amy

+0

, что имеет смысл. но делать то, что вы хотите в пандах, это в основном: 'df = pd.read_csv (csvfile); print df [df.gender == 'Male']; print df [df.gender == 'Female'] '. что кажется более простым. но в любом случае работает. – acushner

ответ

3

Я использовал бы модуль csv вместе с defaultdict от collections для этого. Скажем, это хранится в файле под названием test.csv:

>>> import csv 
>>> from collections import defaultdict 
>>> with open('test.csv', 'rb') as fin: data = list(csv.reader(fin))[1:] 
>>> gender_dict = defaultdict(set) 
>>> for idx, name, gender, alive in data: 
    gender_dict[gender].add(name) 

>>> gender_dict 
defaultdict(<type 'set'>, {'Male': ['Adam', 'Marc'], 'Female': ['Bella']}) 

У вас теперь есть словарь. Каждый ключ является уникальным значением из гендерного столбца. Каждое значение представляет собой набор, поэтому вы получите только уникальные предметы. Обратите внимание, что мы добавили 'Adam' дважды, но видим только один в результирующем наборе.

Вам не нужен defaultdict, но он позволяет использовать менее шаблонный код, чтобы проверить, существует ли ключ.

EDIT: Это может помочь улучшить видимость самих данных. Учитывая, что ваш код, я могу сделать следующие предположения:

  • является итерацию (список, кортеж, что-то в этом роде), содержащие словари.

  • В каждом словаре содержится ключ 'gender'. Если он не включил не менее 'gender', при попытке его фильтрации вы получите ключевую ошибку.

  • В каждом словаре есть ключ 'name', он выглядит.

Вместо того, чтобы делать все это регулярное выражение, что об этом?

>>> gender_dict = {'Male': set(), 'Female': set()} 
>>> for item in input_file_data: 
     gender_dict[item['gender']].add(item['name']) 

Вы можете использовать item.get('name') вместо item['name'], если не каждая запись будет иметь имя.

Редактировать # 2: Хорошо, первое, что вам нужно сделать, это получить данные в согласованное состояние.Мы можем абсолютно добраться до точки, где у вас есть имя столбца (пол, индекс, живое, все, что вы хотите) и набор уникальных имен, соответствующих этим столбцам. Что-то вроде этого:

data_dict = {'gender': 
       {'Male': ['Adam', 'Marc'], 
        'Female': ['Bella']} 
      'alive': 
       {'Y': ['Adam', 'Marc'], 
        'N': ['Bella', 'Adam']} 
      'index': 
       {1: ['Adam'], 
        2: ['Bella'], 
        3: ['Marc']} 
       } 

Если это то, что вы хотите, вы можете попробовать это:

>>> data_dict = defaultdict(lambda: defaultdict(lambda: defaultdict(set))) 
>>> for element in input_file_data: 
     for key, value in element.items(): 
      if key != 'name': 
       data_dict[key][value].add(element[name]) 

Это должен получить, что вы хотите, я думаю? Я не могу проверить, поскольку у меня нет данных, но попробуйте.

+0

Спасибо за ваш ответ. Виноват. Я забыл упомянуть, что у меня есть несколько файлов, и не все файлы имеют одинаковые имена заголовков. Поэтому я не могу их жестко закодировать. – amy

+1

Независимо от имен заголовков, если столбцы, по крайней мере, в одном порядке, вы в порядке. Я не говорю напрямую о каких-либо заголовках. «Idx, name, gender, alive in data» просто распаковывает каждую строку из CSV и присваивает значение каждому из имен. Неважно, что такое фактическое имя столбца. Это то, что вы имели ввиду? – paidhima

+0

К сожалению, это также не так. Файлы могут быть разными. :(У меня есть еще несколько функций в скрипте в настоящее время, и он возвращает пустой файл, если нет файла с заданным заголовком. – amy

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