Отображение и повторение вложенных словарей

#python #dictionary #matrix #iteration

#python #словарь #матрица #итерация

Вопрос:

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

Я пытаюсь создать перекрестную матрицу, которая связывает отзывы между пользователями: список рецензентов, их отдельные обзоры, метаданные, связанные с обзорами.

ПРИМЕЧАНИЕ: это написано на Python 2.7.10 — я не могу использовать Python 3, потому что устаревшие системы, на которых это будет выполняться, yada yada.

Для инициализации у меня есть следующее:

 print 'nCompiling Review Maps... ';
LbidMap = {};
TbidMap = {};
for user in reviewer_idx :
    for review in data['Reviewer Reviews'][user] :
        reviewInfo = data['Review Information'][review];
        stars = float(reviewInfo['stars']);
        bid = reviewInfo['business_id'];

        # Initialize lists where necessary
        # !!!! I know this is probably not effective, but am unsure of
        #  a better method. Open to suggestions !!!!!
        if bid not in LbidMap:
            LbidMap[bid] = {};
            TbidMap[bid] = {};
        if stars not in LbidMap[bid] :
            LbidMap[bid][stars] = {};
        if user not in TbidMap[bid] :
            TbidMap[bid][user] = {};

        # Track information on ratings to each business
        LbidMap[bid][stars][user] = review;
        TbidMap[bid][user][review] = stars;
  

(где ‘bid’ — сокращение от «Business ID», pos_list — это ввод, вводимый пользователем во время выполнения)

Затем я продолжаю и пытаюсь создать сопоставление пользователей, которые дали «положительный» отзыв бизнесу T, который также дал бизнесу L рейтинг X (например, 5 человек оценили бизнес L на 4/5 звезд, сколько из этих людей также дали «положительный» отзыв бизнесу T?)

Для сопоставления у меня есть следующее:

 # Determine and map all users who rated business L as rL
#  and gave business T a positive rating
print 'nCross matching ratings across businesses';
cross_TrL = [];
for Tbid in TbidMap :
    for Lbid in LbidMap :
        # Ensure T and L aren't the same business
        if Tbid != Lbid :
            for stars in LbidMap[Lbid] :
                starSum = len(LbidMap[Lbid][stars]);
                posTbid = 0;
                for user in LbidMap[Lbid][stars] :
                    if user in TbidMap[Tbid] :
                        rid = LbidMap[Lbid][stars][user];
                        print 'Tbid:%s  Lbid:%s  user:%s  rid:%s'%(Tbid, Lbid, user, rid);
                        reviewRate = TbidMap[Tbid][user][rid];
                        # If true, then we have pos review for T from L
                        if reviewRate in pos_list :
                            posTbid  = 1;
                numerator = posTbid   1;
                denominator = starSum   1;
                probability = float(numerator) / denominator;
  

В настоящее время я получаю следующую ошибку (также предоставляется распечатка текущих переменных):

 Tbid:OlpyplEJ_c_hFxyand_Wxw  Lbid:W0eocyGliMbg8NScqERaiA  user:Neal_1EVupQKZKv3NsC2DA  rid:TAIDnnpBMR16BwZsap9uwA
Traceback (most recent call last):
  File "run_edge_testAdvProb.py", line 90, in <module>
    reviewRate = TbidMap[Tbid][user][rid];
KeyError: u'TAIDnnpBMR16BwZsap9uwA'
  

Итак, я знаю, что ошибка ключа связана с тем, каким должен быть rid (идентификатор проверки) в данный конкретный момент в TbidMap, однако мне кажется, что ключ каким-то образом не был включен в первый блок кода инициализации.

Что я делаю не так? Кроме того, приветствуются предложения о том, как улучшить тактовые циклы во втором блоке кода.


РЕДАКТИРОВАТЬ: я понял, что я пытался найти rid Tbid, используя rid from Lbid, однако rid он уникален для каждого обзора, поэтому у вас не будет Tbid.rid == Lbid.rid .

Обновлен второй блок кода, как таковой:

 cross_TrL = [];
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] :
                starSum = len(LbidMap[Lbid][stars]);
                posTbid = 0;
                # For each review check if user rated the Tbid
                for Lreview in LbidMap[Lbid][stars] :
                    user = LbidMap[Lbid][stars][Lreview];
                    if user in TbidMap[Tbid] :
                        # user rev'd Tbid, get their Trid 
                        #  and see if they gave Tbid a pos rev
                        for Trid in TbidMap[Tbid][user] :
                            # Currently this does not account for multiple reviews
                            #  given by the same person. Just want to get this 
                            #  working and then I'll minimize this
                            Tstar = TbidMap[Tbid][user][Trid];
                            print 'Tbid:%s  Lbid:%s  user:%s  Trid:%s'%(Tbid, Lbid, user, Trid);
                            if Tstar in pos_list :
                                posTbid  = 1;
                numerator = posTbid   1;
                denominator = starSum   1;
                probability = float(numerator) / denominator;
                evaluation = {'Tbid':Tbid, 'Lbid':Lbid, 'star':stars, 'prob':probability}
                cross_TrL.append(evaluation);
  

Все еще медленно, но я больше не получаю сообщение об ошибке.

Комментарии:

1. Добавьте код, чтобы явно проверить, находится ли rid в TbidMap . Если это не так, то вы знаете, где начинается проблема.

2. @martineau — мне ясно, что rid этого нет TbidMap , хотя его следует добавить в строку TbidMap[bid][user][review] = stars; (конец первого блока кода). Если rid существует, как это происходит с момента повторения, то я не понимаю, почему он не привязан к пользовательскому подразделу в TbidMap. Я почти задаюсь вопросом, переписывается ли он? Но я недостаточно разбираюсь в python, чтобы полностью понять, так ли это.

3. Кажется слишком сложным, судя по тому, как вы описываете свою проблему, я думаю, что некоторый SQL с несколькими объединениями может дать вам ответы, которые вы хотите, более легко.