2014-04-15 6 views
0

Я пытаюсь выполнить несколько операций над большим фреймворком данных (~ 3 миллиона строк).
Используя небольшой тестовый набор, представляющий мои данные, я придумал решение.
Однако сценарий работает очень медленно при использовании большого набора данных в качестве входных данных.
Работа в группах Pandas

Вот основной цикл приложения:

def run(): 
    df = pd.DataFrame(columns=['CARD_NO','CUSTOMER_ID','MODIFIED_DATE','STATUS','LOYALTY_CARD_ENROLLED']) 

    foo = input.groupby('CARD_NO', as_index=False, sort=False) 

    for name, group in foo: 
     if len(group) == 1: 
      df = df.append(group) 
     else: 
      dates = group['MODIFIED_DATE'].values 
      if all_same(dates): 
       df = df.append(group[group.STATUS == '1']) 
      else: 
       df = df.append(group[group.MODIFIED_DATE == most_recent(dates)]) 

    path = '' 
    df.to_csv(path, sep=',', index=False) 

Логика следующим образом:
Для каждого CARD_NO
- если есть только один CARD_NO, добавьте строку в новой dataframe
- если есть 1 из того же CARD_NO, проверьте MODIFIED_DATE,
- если MODIFIED_DATE отличаются, возьмите строку с самой последней датой
- если все MODIFIED_DATES являются eq UAL, принимать в зависимости от того строка имеет STATUS = 1

Замедление происходит на каждой итерации вокруг,

input.groupby('CARD_NO', as_index=False, sort=False) 

Я в настоящее время пытается распараллелить цикл путем разделения групп, возвращаемые выше заявление, но Я не уверен, что это правильный подход ...

Я пропустил основные функции Панд?
Есть ли лучший, более Pandas-esque способ решения этой проблемы?

Любая помощь с благодарностью.
Спасибо.

+0

Где вы читаете данные? Это файл csv? – nitin

+0

Да. Это около 145 мб. – Zihs

+0

постоянно добавление неэффективно; добавьте сгенерированный фрейм для каждой группы в список; concat в конце – Jeff

ответ

0

Я написал значительное улучшение времени работы. Операторы return, по-видимому, меняют структуру данных, значительно улучшая время работы (~ 30 минут для 3 миллионов строк) и избегая необходимости в дополнительных структурах данных.

def foo(df_of_grouped_data): 
    group_length = len(df_of_grouped_data) 

    if group_length == 1: 
     return df_of_grouped_data 
    else: 
     dates = df_of_grouped_data['MODIFIED_DATE'].values 
     if all_same(dates): 
      return df_of_grouped_data[df_of_grouped_data.STATUS == '1'] 
     else: 
      return df_of_grouped_data[df_of_grouped_data.MODIFIED_DATE == most_recent(dates)] 

result = card_groups.apply(foo) 
0

Два общих советов:

  1. Для зацикливание над объектом GroupBy, вы можете попробовать apply. Например,

    grouped = input.groupby('CARD_NO', as_index=False, sort=False)) 
    grouped.apply(example_function) 
    

    Здесь example_function вызывается для каждой группы в вашем объекте GroupBy. Вы можете написать example_function, чтобы добавить к структуре данных самостоятельно, или если у нее есть возвращаемое значение, pandas попытается объединить возвращаемые значения в один фрейм данных.

  2. Добавление строк в dataframes происходит медленно. Возможно, вам лучше построить какую-либо другую структуру данных с каждой итерацией цикла, а затем построить ваш фреймворк в конце. Например, вы можете составить список dicts.

    data = [] 
    grouped = input.groupby('CARD_NO', as_index=False, sort=False) 
    
    
    def example_function(row,data_list): 
        row_dict = {} 
        row_dict['length'] = len(row) 
        row_dict['has_property_x'] = pandas.notnull(row['property_x']) 
        data_list.append(row_dict) 
    
    grouped.apply(example_function, data_list=data) 
    pandas.DataFrame(data) 
    
Смежные вопросы