Ich habe Daten in einem 3D-Wörterbuch als:

 movieid, date,customer_id,views
 0, (2011,12,22), 0, 22
 0, (2011,12,22), 1, 2
 0, (2011,12,22), 2, 12
 .....
 0, (2011,12,22), 7, 2
 0, (2011,12,23), 0, 123

.. im Grunde genommen geben die Daten an, wie oft ein Film pro Tag gesehen wurde .. von jedem Kunden (es gibt nur 8 Kunden) ..

Jetzt möchte ich berechnen, im Durchschnitt , wie oft ein Kunde einen Film gesehen hat.

Also im Grunde genommen

    movie_id,customer_id, avg_views
     0, 0, 33.2
     0, 1 , 22.3

  and so on

Was ist der pythonische Weg, um dies zu lösen.

Vielen Dank

Bearbeiten:

 data = defaultdict(lambda : defaultdict(dict))
 date = datetime.datetime(2011,1,22)
 data[0][date][0] = 22
 print data
defaultdict(<function <lambda> at 0x00000000022F7CF8>, 
 {0: defaultdict(<type 'dict'>, 
 {datetime.datetime(2011, 1, 22, 0, 0): {0: 22}}))

Angenommen, es gibt nur 2 Kunden, 1 Film und Daten im Wert von 2 Tagen

 movie_id, date, customer_id,views
 0 , 2011,1,22,0,22
 0 , 2011,1,22,1,23
 0 , 2011,1,23,0,44

Hinweis: Der Kunde 1 hat am 23. Januar keine Film-ID 0 gesehen. Jetzt würde die Antwort

 movie_id,customer_id,avg_views
  0   , 0 ,    (22+44)/2
  0,    1,      (23)/1
1
Mohit 26 Nov. 2012 im 20:01

3 Antworten

Beste Antwort

sum macht dies einfach. In meiner Originalversion habe ich häufig dict.keys() verwendet, aber wenn Sie ein Wörterbuch durchlaufen, erhalten Sie standardmäßig die Schlüssel.

Diese Funktion berechnet eine einzelne Zeile des Ergebnisses:

def average_daily_views(movie_id, customer_id, data):
    daily_values = [data[movie_id][date][customer_id] for date in data[movie_id]]
    return sum(daily_values)/len(daily_values)

Dann können Sie es einfach schleifen, um die gewünschte Form zu erhalten. Vielleicht:

def get_averages(data):
    result = [average_daily_views(movie, customer, data) for customer in 
              data[movie] for movie in data]
1
PeterBB 26 Nov. 2012 im 16:36

Ich denke, Sie sollten Ihre Daten ein wenig umstrukturieren, um Ihren Zwecken besser zu dienen:

restructured_data = collections.defaultdict(lambda: collections.deafualtdict(collections.defaultdict(int)))
for movie in data:
    for date in data[movie]:
        for customer,count in date.iteritems():
            restructured_data[customer_id][movie_id][date] += count

averages = collections.defaultdict(dict)
for customer in restructured_data:
    for movie in restructured_data[customer]:
        avg = sum(restructured_data[customer][movie].itervalues())/float(len(restructured_data[customer][movie]))
        averages[movie][customer] = avg

for movie in averages:
    for customer, avg in averages[movie].iteritems():
        print "%d, %d, %f" %(movie, customer, avg)

Hoffe das hilft

1
inspectorG4dget 26 Nov. 2012 im 16:40

Meine Vision ist:

pool = [
    (0, (2011,12,22), 0, 22),
    (0, (2011,12,22), 1, 2),
    (0, (2011,12,22), 2, 12),
    (0, (2011,12,22), 7, 2),
    (0, (2011,12,23), 0, 123),
]


def calc(memo, row):
    if (row[2] in memo.keys()):
        num, value = memo[2]
    else:
        num, value = 0, 0

    memo[row[2]] = (num + 1, value + row[3])
    return memo

# dic with sum and number
v = reduce(calc, pool, {})
# calc average
avg = map(lambda x: (x[0], x[1][1] / x[1][0]), v.items())

print dict(avg)

Wobei avg - ein Wörterbuch mit key = customer_id und value - Durchschnitt der Ansichten ist

1
Rustem 26 Nov. 2012 im 16:24