1

これが私の問題です。

次のように、リストのリストがあります。

linesort=[
  ['Me', 1, 596], 
  ['Mine', 1, 551], 
  ['Myself', 1, 533], 
  ['Myself', 1, 624], 
  ['Myself', 1, 656], 
  ['Myself', 1, 928], 
  ['Theirs', 1, 720], 
  ['Theirs', 1, 1921], 
  ['Them', 1, 716], 
  ['Themselves', 1, 527]
]

各サブリストは、参加者が単語を正しくまたは間違って分類するのにかかった時間 (2 番目の値) と、応答するまでの時間 (3 番目の値) を表します。私がやりたいことは、単語、各リストの 2 番目の値の合計、および 3 番目の値の平均を含むリストの別のリストを返すことです。

基本的に、各サブリストの最初の要素を比較し、それらが等しい場合は、2 番目の要素の合計と 3 番目の要素の平均を計算する必要があります。

これを手動で行うことはできましたが (変数を手動で割り当てて作成するなど)、ループ内でこれを行う試みはすべて失敗しました。この種のデータを含む 2 つの非常に大きなテキスト ファイルがあることを考えると、プログラムによる解決策があれば幸いです。

役立つかもしれないいくつかのポイント: 各テストで使用される単語は事前に知っていますが、それらがどこに表示されるかはわかりません (また、刺激のいずれかのグループに表示される場合でも)。誰でもこれで私を助けることができますか?

Ubuntu 10.04 で Python 2.6.5 を使用しています。

4

3 に答える 3

3

美しいものではありませんが:

from collections import defaultdict

linesort = [['Me', 1, 596], ['Mine', 1, 551], ['Myself', 1, 533], ['Myself', 1, 624],
            ['Myself', 1, 656], ['Myself', 1, 928], ['Theirs', 1, 720], 
            ['Theirs', 1, 1921], ['Them', 1, 716], ['Themselves', 1, 527]]

d = defaultdict(list)
for line in linesort:
    d[line[0]].append(line[1:])


output = {}
for x,val in d.items():
    svals = [y[1] for y in val]
    output[x] = [sum([y[0] for y in val]), sum(svals) / len(svals)] # need to be modified if you need float value

print output
>>> {'Mine': [1, 551], 'Theirs': [2, 1320], 'Me': [1, 596], 'Them': [1, 716], 'Themselves': [1, 527], 'Myself': [4, 685]}

または groupby を使用します (これは最も効率的ではなく、初期データを並べ替える必要があることに注意してください):

from itertools import groupby

res = {}
for key, gen in groupby(sorted(linesort), key=lambda x: x[0]):
    val = list(gen)
    svals = [y[2] for y in val]
    res[key] = [sum([y[1] for y in val]), sum(svals) / float(len(svals))]

ただし、以前のサンプルはすべて辞書を返すため、リストを取得したい場合は、コードを少し変更するだけで済みます。

from itertools import groupby

res = []
for key, gen in groupby(sorted(linesort), key=lambda x: x[0]):
    val = list(gen)
    svals = [y[2] for y in val]
    res.append([key, sum([y[1] for y in val]), sum(svals) / float(len(svals))])

print res
>>> [['Me', 1, 596.0], ['Mine', 1, 551.0], ['Myself', 4, 685.25], ['Theirs', 2, 1320.5], ['Them', 1, 716.0], ['Themselves', 1, 527.0]]
于 2011-06-21T12:16:47.647 に答える
1

私の冗長な解決策

#!/usr/bin/env python

import collections

linesort=[['Me', 1, 596], ['Mine', 1, 551], ['Myself', 1, 533], ['Myself', 1, 624],
          ['Myself', 1, 656], ['Myself', 1, 928],['Theirs', 1, 720], ['Theirs', 1, 1921],
          ['Them', 1, 716], ['Themselves', 1, 527]]
new=[]

d=collections.defaultdict(list)
for i in linesort:
    d[i[0]].append(i[1:])

for k,v in d.iteritems():
    s=sum([i[0] for i in v])
    avg=sum([i[1] for i in v]) / len(v)

    new.append([k,s,avg])

for i in new: print i

出力:

['Me', 1, 596]
['Myself', 4, 685]
['Theirs', 2, 1320]
['Mine', 1, 551]
['Themselves', 1, 527]
['Them', 1, 716]
于 2011-06-21T12:28:50.917 に答える
1

これが私の簡単な解決策です:

#!/usr/bin/python

linesort=[['Me', 1, 596], ['Mine', 1, 551], ['Myself', 1, 533], ['Myself', 1, 624], ['Myself', 1, 656], ['Myself', 1, 928], ['Theirs', 1, 720], ['Theirs', 1, 1921], ['Them', 1, 716], ['Themselves', 1, 527]]

cnts = {};
sums = {};
# here we count occurrences of each word (cnts),
# and we compute the the sum of second elements of each input list
for list in linesort:
  cnts[list[0]] = cnts.get(list[0], 0) + 1;
  sums[list[0]] = sums.get(list[0], 0) + list[1];

# now that we know the occurrences for each work we can compute
# the averages of the third elements of each input list 
avgs = {};
for list in linesort:
  avgs[list[0]] = avgs.get(list[0], 0) + list[2] / cnts[list[0]];

# we build the result as a list of lists
result = [];
for word in avgs:
  result.append([word, sums[word], avgs[word]]);

print result;

出力は次のとおりです。

[['Me', 1, 596], ['Myself', 4, 685], ['Theirs', 2, 1320], ['Mine', 1, 551], ['Themselves', 1, 527], ['Them', 1, 716]]
于 2011-06-21T12:52:43.290 に答える