1

シナリオは次のとおりです。整数の(同じ長さの) n個のリストと(実際には同じ長さの)アキュムレータが与えられた場合、要素ごとの合計をインプレースで累積します。インプレース制約は、リストのdictに値を累積するためにここにあります(ハム...かなり明確ではありません。以下の例を参照してください)

編集:私はnumpyを含まない解決策を探しています

# My lists are long (they are actually pixels in 1000x1000 images)
# but I keep l low for the sake of the example
l = 5

# Values here are arbitrary and won't be repeated in the real word
# e.g. list 1 might be [41,15,0,2,3], etc.
lists = [
   {'id': 1, 'values': [12]*l},
   {'id': 2, 'values': [42]*l},
   {'id': 2, 'values': [25]*l},
   {'id': 1, 'values': [6]*l},
]

maps = {
  1: [0]*l,
  2: [0]*l
}

for item in lists:
  # Get the "target" for this list
  target = maps[item['id']]

  # Element-wise addition of item['values'] to target here!

  # This won't work
  target = map(lambda x,y:x+y, target, item['values'])
  # This neither
  target = [(x+y) for x,y in itertools.izip(target,item['values'])]

  # For either of the previous to work, I need to re-assign
  # the result to 'target', like so
  maps[item['id']] = target

それが機能し、私はそれと一緒に専門的に生きることができますが、私は個人的にはできません。

誰かが今夜私をよく眠らせることができますか?

4

5 に答える 5

2

numpyを見てください。コードは次のように書くことができます:

import numpy as np

l = 5
lists = [
   {'id': 1, 'values': np.array([12]*l)},
   {'id': 2, 'values': np.array([42]*l)},
   {'id': 2, 'values': np.array([25]*l)},
   {'id': 1, 'values': np.array([6]*l)},
]

maps = {
  1: np.zeros(l),
  2: np.zeros(l)
}

for item in lists:
   maps[item['id']] += item['values']

それ以上のループなしで、2D(画像)にも適応させることができます。

于 2012-08-31T12:57:07.270 に答える
1

辞書のリストをテーブルとして使用しようとしているようです。スペシャリストデータ型(このために最適化されています)の使用を検討する必要があります。私の提案はパンダのデータフレームです。

于 2012-08-31T12:59:11.010 に答える
1

私はあなたのコードを実際に理解するために時間を費やしていませんが、このようなものがうまくいく可能性があるように私には思えます:

target[:] = [(x+y) for x,y in itertools.izip(target,item['values'])]

ここでの唯一の違いはtarget[:]、の代わりですtarget。リストのスライスに割り当てるときは、その割り当てをその場で行います。検討:

a = [1,2,3,4]
a[1:3] = ["foo","bar"]
print(a)  # [1, 'foo', 'bar', 4]

これにより、一時的なリストが作成されます(少なくとも、CPythonでは-おそらく、JITコンパイルを使用したpypyのようなもので最適化できます...)。これを回避するには、ジェネレーターを使用できます(ただし、コードの実行速度が低下する可能性があります)。

a[1:3] = (x for x in iterable)

したがって、最終的な解決策はおそらく(テストされていない)である可能性があります。

target[:] = ((x+y) for x,y in itertools.izip(target,item['values']))
于 2012-08-31T13:23:57.590 に答える
1

に追加するときに一時的なものを本当に避けようとする場合は、次のようなことをtargetしてみませんか。

for (i, v) in enumerate(item['values']):
    target[i] += v

あなたのループで?そしてtarget、その場で変更するときに、それを再割り当てする必要はありませんmaps[item["id"]]...

于 2012-08-31T14:09:37.347 に答える
0

この混乱は、変数の再割り当てに起因していますかtarget?次のことを考慮してください。

x = [3]
target = x[0] # target = 3
target = 4
print x # prints [3] # x has not been changed

ダミー変数に割り当てるのではなく、このインプレース変更を1行で行うことができますtarget何かのようなもの:

maps[item['id']] = map(lambda x,y:x+y, maps[item['id']], item['values'])
于 2012-08-31T13:06:55.730 に答える