2015-06-03 2 views
2

Постановка задачи:Python - прочитать определенные строки в текстовом файле на основе состояния

У меня есть файл, как показано ниже.

name | date | count 
John | 201406 | 1 
John | 201410 | 2 
Mary | 201409 | 180 
Mary | 201410 | 154 
Mary | 201411 | 157 
Mary | 201412 | 153 
Mary | 201501 | 223 
Mary | 201502 | 166 
Mary | 201503 | 163 
Mary | 201504 | 169 
Mary | 201505 | 157 
Tara | 201505 | 2 

Файл показывает данные для трех человек: Джон, Мэри и Тара в течение нескольких месяцев. Я хотел бы проанализировать эти данные и создать тег статуса для каждого человека, то есть активного, неактивного или нового.

Человек активен, если у них есть записи для 201505 и других предыдущих месяцев - как Мэри

Людей неактивны, если они не имеют записей для 201505 - как Джон

Лица является новым, если они ТОЛЬКО 1 запись для 201505 - как Тара.

Кроме того, если человек активен, я бы хотел получить медиану их последние 5 баллов. Например, для Мэри я хотел бы получить среднее значение ((157 + 169 + 163 + 166 + 223)/5).

Вопрос:

Я хотел бы понять, как я должен читать этот файл в Python 2.7 для того, чтобы выполнить мои требования. Я начал со следующего, но не был уверен, как получить предыдущие записи (например, предыдущие строки в файле) для определенного человека.

for line in data: 
    col = line.split('\t') 
    name = col[0] 
    date = col[1] 
    count = col[2] 
+0

Рассмотрите возможность использования ' Pandas', то вы можете использовать функцию '.groupby ('name')', чтобы смотреть на каждого человека отдельно. – vk1011

ответ

3
import pandas as pd: 
df = pd.read_csv('input_csv.csv') # This assumes you have a csv format file 
names = {} 
for name, subdf in df.groupby('name'): 
    if name not in names: 
     names[name] = {} 
    if (subdf['date']==201505).any(): 
     if subdf['count'].count()==1: 
      names[name]['status'] = 'new' 
     else: 
      names[name]['status'] = 'active' 
      names[name]['last5median'] = subdf['count'].tail().median() 
    else: 
     names[name]['status'] = 'inactive' 


>>> 
{'John': {'status': 'inactive'}, 
'Mary': {'last5median': 166.0, 'status': 'active'}, 
'Tara': {'status': 'new'}} 
+0

Означает ли это, что у нас есть строка заголовка в txt-файле? Что относительно случая, когда нет файла заголовка? – activelearner

+0

Да, это предполагает, что файл имеет строку заголовка. Если заголовков нет, и вы хотите явно указать имена столбцов, прочитайте в файле следующим образом: 'df = pd.read_csv ('input_csv.csv', names = ['name', 'date', 'count']) ' – vk1011

+0

Спасибо. Где мы говорим программе, чтобы получить медиану последних 5 в именах [name] ['last5median'] = subdf ['count']. Tail(). Median()? Что, если я хочу за последние 8? – activelearner

2

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

import re 

spl = """name | date | count 
John | 201406 | 1 
John | 201410 | 2 
Mary | 201409 | 180 
Mary | 201410 | 154 
Mary | 201411 | 157 
Mary | 201412 | 153 
Mary | 201501 | 223 
Mary | 201502 | 166 
Mary | 201503 | 163 
Mary | 201504 | 169 
Mary | 201505 | 157 
Tara | 201505 | 2""" 

dicto = {} 

listo = re.split("\\||\n",spl) 
listo = [x.strip() for x in listo] 
for x in range(3,len(listo),3): 
    try: 
     dicto[listo[x]].append([listo[x+1],listo[x+2]]) 
    except KeyError: 
     dicto[listo[x]]= [] 
     dicto[listo[x]].append([listo[x+1],listo[x+2]]) 

print (dicto.get('John')) 

Выход:

[['201406', '1'], ['201410', '2']] 

Итак, теперь у вас есть все данные, для всех пользователей в Словаре из dicts, и вы можете делать с ними то, что вы хотите

+0

Если мой исходный файл является текстовым файлом с разделителями табуляции, как бы я прочитал его в переменной spl и как изменилась бы функция re.split? Благодаря! – activelearner

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