2016-01-21 4 views
-1

Учитывая набор данных из миллиона данных, я хочу рассчитать среднюю цену предметов. Некоторые элементы itemID реплицируются, и это ключ.Рассчитать средние кортежи в одном миллионном наборе данных

К примеру, учитывая следующие словари:

res = { 
    '155': ['3','4','5'], 
    '222': ['1'], 
    '345': ['6','8','10'] 
    . 
    (+ 1 million more lines) 
    .} 

Я хочу, чтобы рассчитать среднюю цену для каждого Itemid и возвращает словарь. Ожидаемый результат будет:

{'155': ['4'], 
'222': ['1'], 
'345': ['8'] 
. 
. 
.} 

, где целое число рядом с itemid - это средняя цена.

Я хочу распаковать список res и рассчитать среднюю цену перед возвратом результата в качестве словаря.

for x, y in res: 
// calculate average and add into new dictionary 

Однако терминал показывает, что существует проблема:

----> 9  for k, l in res: 
10   print(k) 
11 
ValueError: too many values to unpack (expected 2) 

я должен перебрать 1 млн наборов данных, чтобы получить среднюю цену? Любая помощь будет отличной!

+0

'(6 + 8 + 10)/3' равно 8. Можете ли вы объяснить,' 345: 10'? – TigerhawkT3

+2

И вы уверены, что получаете именно этот «ValueError»?Я получаю только это, если сменить эти целые ключи на строки. – TigerhawkT3

+0

Это действительно не вызывает «ValueError». Измените свой вопрос и поставьте словарь *, как вы использовали его в своем коде *. Неоднозначность никому не помогает. –

ответ

1

Атрибут словаря объекта итерации по его клавишам, поэтому, когда вы перебираете свой словарь, вы выполняете итерацию по клавишам, и вам нужна только одна переменная throwaway.

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

for key, value in res.items: 
     # do stuff 

И для вашей задачи вы можете использовать словарь понимание, чтобы вычислить среднее значение ваших цен:

{key:sum(value)/len(value) for key,value in res.items()} 

Примечание: Если вы используете python 2.X вместо items(), используйте iteritems(), который возвращает итератор элементов и более оптимизирован с точки зрения использования памяти.

Также отметим, что (1) не кортеж, и вы должны преобразовать его в (1,) для того, чтобы отказаться от получения ValueError:

>>> res = { 
... 155: (3,4,5), 
... 222: (1,), 
... 345: (6,8,10)} 
>>> 
>>> {key:sum(value)/len(value) for key,value in res.items()} 
{345: 8, 155: 4, 222: 1} 

Но если это не представляется возможным, чтобы изменить это значение, которое нужно проверить тип значения перед вызовом функции len() этого:

{key:sum(value)/len(value) if isinstance(value,tuple) else value for key,value in res.items()} 

>>> res = { 
... 155: (3,4,5), 
... 222: (1), 
... 345: (6,8,10)} 
>>> 
>>> {key:sum(value)/len(value) if isinstance(value,tuple) else value for key,value in res.items()} 
{345: 8, 155: 4, 222: 1} 
+0

Спасибо! вы предсказывали, с какими еще проблемами я столкнусь! Благодаря! – user2837332

0

Использование iteritems

for x, y in res.iteritems(): 
    // calculate average and add into new dictionary 

Если вы делаете это как for x, y in res: то только ключи возвращаются не значения, следовательно, ошибка, вы делаете x, y = key поэтому он будет давать ошибку слишком много значений для распаковки. Принимая во внимание, что iteritems() возвращает (key, value) кортеж, вам необходимо iteritems(). Для python3 используйте res.items() вместо res.iteritems(), который предназначен для python2.

+2

Обратите внимание, что данное сообщение об ошибке не соответствует указанному коду. – TigerhawkT3

+0

@ TigerhawkT3 вы правы. Он должен быть 'TypeError' для объектов int. Но может быть OP вместо копирования значений из его исходного кода, здесь введите новые значения. Таким образом, он мог бы использовать строки в своем исходном коде, следовательно, «ValueError». Может быть очищен только OP :). –

+0

Да, я работаю над данными компании, и я заменил данные поддельными. Большое спасибо, вы многое помогли! – user2837332

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