#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 с несколькими объединениями может дать вам ответы, которые вы хотите, более легко.