2016-10-11 3 views
1

У меня есть набор данных, для которых значения, определенные для соответствия определенным критериям, используются для вычисления вероятностей как части суммирования. В настоящее время я держу данные во вложенных словарях, чтобы упростить процесс детерминированной обработки.Эффективная итерация через вложенные словари python

Алгоритм, который я использую, оказывается очень дорогим и через некоторое время перегружает память.

psudocode для обработки заключается в следующем:

for businessA in business : # iterate over 77039 values 
    for businessB in business : # iterate over 77039 values 
     if businessA != businessB : 
      for rating in business[businessB] : # where rating is 1 - 5 
       for review in business[businessB][rating] : 
        user = reviewMap[review]['user']; 
        if user in business[businessA]['users'] : 
         for users in business[businessA]['users'] : 
          # do something 
       # do probability 
       # a print is here 

Как я могу написать выше более эффективно поддерживать точное вероятностное суммирование для каждого businessA?


EDIT включая исходный код - здесь, businessA и businessB находятся в отдельно словарях, однако это отметить, что они имеют те же businessIDs (BID) в каждом. Это просто изменение того, что значение для каждой пары ключ: значение.

def crossMatch(TbidMap) : 
    for Tbid in TbidMap : 
     for Lbid in LbidMap : 
      # Ensure T and L aren't the same business 
      if Tbid != Lbid : 
       # Get numer of reviews at EACH STAR rate for L 
       for stars in LbidMap[Lbid] : 
        posTbid = 0; 
        # For each review check if user rated the Tbid 
        for Lreview in LbidMap[Lbid][stars] : 
         user = reviewMap[Lreview]['user']; 
         if user in TbidMap[Tbid] : 
          # user rev'd Tbid, get their Trid & see if gave Tbid pos rev 
          for Trid in TbidMap[Tbid][user] : 
           Tstar = reviewMap[Trid]['stars']; 
           if Tstar in pos_list : 
            posTbid += 1; 
        #probability calculations happen here 
+2

Можете ли вы предоставить образцы входных данных и выходных данных? Вы использовали 'if BusinessA! = BusinessB:' что это? –

+0

businessA, BusinessB - это уникальные предприятия в словаре таких предприятий, что businessA не является BusinessB (например, McDonalds не является Wendy's). –

+2

Вы держите 'бизнес' в памяти? Как сохранить результаты? –

ответ

2

Есть более 5 миллиард комбинаций компаний в наборе данных, который действительно собирается подчеркнуть память вне. Я думаю, что вы сохраняете все результаты в памяти; вместо этого я буду делать промежуточные дампы в базе данных и освобождать ваши контейнеры. Это эскиз подхода, поскольку у меня нет реальных данных для тестирования, и вам может быть легче реагировать на ваши трудности по мере их возникновения. В идеале был бы промежуточный контейнер для вложенных списков, так что вы могли бы использовать executemany, но это так сильно вложено с сокращенными именами и без тестовых данных, с которыми трудно следовать.

import sqlite3 

def create_interim_mem_dump(cursor, connection): 

    query = """CREATE TABLE IF NOT EXISTS ratings(
      Tbid TEXT, 
      Lbid TEXT, 
      posTbid TEXT) 
      """ 
    cursor.execute(query) 
    connection.commit() 


def crossMatch(TbidMap, cursor, connection) : 
    for Tbid in TbidMap : 
     for Lbid in LbidMap : 
      # Ensure T and L aren't the same business 
      if Tbid != Lbid : 
       # Get numer of reviews at EACH STAR rate for L 
       for stars in LbidMap[Lbid] : 
        posTbid = 0; 
        # For each review check if user rated the Tbid 
        for Lreview in LbidMap[Lbid][stars] : 
         user = reviewMap[Lreview]['user']; 
         if user in TbidMap[Tbid] : 
          # user rev'd Tbid, get their Trid & see if gave Tbid pos rev 
          for Trid in TbidMap[Tbid][user] : 
           Tstar = reviewMap[Trid]['stars']; 
           if Tstar in pos_list : 
            posTbid += 1; 
        query = """INSERT INTO ratings (Tbid, Lbid, posTbid) 
          VALUES (?, ?, ?)""" 
        cursor.execute(query, (Tbid, Lbid, posTbid)) 
     connection.commit() 



if __name__ == '__main__': 
    conn = sqlite3.connect('collated_ratings.db') 
    c = conn.cursor() 

    create_db = create_interim_mem_dump(c, conn) 
    your_data = 'Some kind of dictionary into crossMatch()' 
    c.close() 
    conn.close() 
Смежные вопросы