2

基本的なデータ処理を実行するために csv ファイルを解析しています。私が作業しているファイルは、次のようにフォーマットされた Web サイトへのユーザー アクティビティのログです。

User ID, Url, Number of Page Loads, Number of Interactions 

ユーザー ID と URL は文字列で、ページ読み込み数とインタラクション数は整数です。

どの URL がインタラクションとページの比率が最も高いかを判断しようとしています。

私が苦労しているのは、一意の値を取得し、列から結果を集計することです。

私は次のコードを書きました:

import csv
from collections import defaultdict

fields = ["USER","URL","LOADS","ACT"]

file = csv.DictReader(open('file.csv', 'rU'), delimiter=",",fieldnames=fields)
file.next()

dict = defaultdict(int)

for i in dict:
    dict[i['URL']] += int(i['LOADS'])

これはうまくいきます。一意の URL のリストと、辞書内の URL ごとの総読み込み数を返します -{ 'URL A' : 1000 , 'URL B' : 500}

問題は、url キーに複数の値を追加しようとすると、困惑することです。

for ループを次のように修正しようとしました。

for i in dict:
    dict[i['URL']] += int(i['LOADS']), int(i['ACT'])

と受け取りTypeError: unsupported operand type(s) for +=: 'int' and 'tuple'ます。2 番目の値がタプルと見なされるのはなぜですか?

だけを追加してみましたがint(i[ACT])、うまくいきました。両方の値を同時に試したときです。

私はpython 2.6.7を使用しています。これを行う方法と、タプルと見なされる理由についてのアイデアはありますか?

4

4 に答える 4

1

int(i['LOADS']), int(i['ACT'])タプルであるため:

>>> 1, 2
(1, 2)

両方の変数を同時に追加する場合は、それらを一緒に追加します。

+= int(i['LOADS']) + int(i['ACT'])

また、ビルトインdictlist型をシャドーイングしています。異なる変数名を使用してください。listシャドウを作成すると、ビルトインを使用できなくなります。

>>> d = {1: 2, 3: 4}
>>> list(d)
[1, 3]
>>> list = 5
>>> list(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
于 2013-01-08T14:44:29.133 に答える
1

両方の値を同時に試したときです。

それらをどのように「追加」しますか?彼らの合計として?

for i in list:
    dict[i['URL']] += int(i['LOADS']) + int(i['ACT'])

また、変数名としてlistandを使用しないでください。dict

import csv
fields = ["USER","URL","LOADS","ACT"]

d = {}
with open('file.csv', 'rU') as f:
    csvr = csv.DictReader(f, delimiter=",",fieldnames=fields)
    csvr.next()
    for rec in csvr:
        d[rec['URL']] = d.get(rec['URL'], 0) + int(rec['LOADS']) + int(rec['ACT'])
于 2013-01-08T14:44:36.127 に答える
1

listを defaultdict コンテナーとして使用することをお勧めします。

import csv
from collections import defaultdict

d = defaultdict(list)
fields = ["USER","URL","LOADS","ACT"]

with open('file.csv', 'rU') as the_file:
    rows = csv.DictReader(the_file, delimiter=",",fieldnames=fields)
    rows.next()

    for row in rows:
        data = (int(row['LOADS']),int(row['ACT']))
        d[row['URL']].append(data)

今、あなたは持っています

d['someurl'] = [(5,17),(7,14)]

これで、任意の合計を実行できます。たとえば、loadsURLのすべてを次のように指定できます。

load_sums = {k:sum(i[0] for i in d[k]) for k in d}
于 2013-01-08T14:53:26.663 に答える
1

オブジェクト指向のアプローチを使用して、情報を保持するクラスを定義できます。他のほとんどの回答よりも冗長ですが、検討する価値があります。

import csv
from collections import defaultdict

class Info(object):
    def __init__(self, loads=0, acts=0):
        self.loads = loads
        self.acts = acts
    def __add__(self, args): # add a tuple of values
        self.loads += args[0]
        self.acts += args[1]
        return self
    def __repr__(self):
        return '{}(loads={}, acts={})'.format(self.__class__.__classname__,
                                              self.loads, self.acts)

summary = defaultdict(Info)
fields = ["USER", "URL", "LOADS", "ACTS"]

with open('urldata.csv', 'rU') as csv_file:
    reader = csv.DictReader(csv_file, delimiter=",", fieldnames=fields)
    reader.next() # skip header
    for rec in reader:
        summary[rec['URL']] += (int(rec['LOADS']), int(rec['ACTS']))

for url,info in summary.items():
    print '{{{!r}: ({}, {})}}'.format(url, info.loads, info.acts)
于 2013-01-08T17:38:19.607 に答える