2016-04-05 23 views
0

このコードを大規模なデータセットで使用すると便利です。ここでは、コードがある、私は徹底的に後でそれを説明します:反復の値をnumpy配列に格納する - Python、Numpy

import numpy as np 
np.set_printoptions(threshold='nan') 

tri_nums = [3, 2, 1] 


paths = [1, 3, 4, 5] 

vol_list = [10, 10, 10, 15, 15, 25] 

n = 0 

array_list = [] 

while n <= len(tri_nums): 
    for num in tri_nums: 
     print "assigning volume", vol_list[sum(tri_nums)-len(vol_list)+1] 
     volume_array = np.zeros(shape = (6, 6)) 
     volume_array[paths[num-1],paths[num]] = vol_list[sum(tri_nums)-len(vol_list)+1] 
     array_list.append(volume_array) 
     print paths[num-1], paths[num] 


    tri_nums.pop(0) 
    paths.pop(0) 
    n+=1 
    print paths 
    print tri_nums 


final_array = sum(array_list) 
print array_list 
print final_array 

tri_numsを皮切り:tri_numsの 値は常にpathsの長さの三角数のリストになります。したがって、pathsのリストは、[1, 3, 4, 5, 6, 8]tri_nums[5, 4, 3, 2, 1]とします。

tri_numsも、vol_listの値の数と相関しています。ご覧のとおり、vol_listには10の3つがあります。 10の数は、tri_numsの最初の値に等しいです。 2つ目の値がtri_numsの場合は、2つの152があります。このパターンは決して変化しません!これの別の例は、(元の場合)リストpathsは、4「ノード」からなる各隣接ノードとの間1,3,4および5ノードさ

paths = [1, 3, 4, 5, 6, 8] 

tri_nums = [5, 4, 3, 2, 1] 

vol_list = [15, 15, 15, 15, 15, 250, 250, 250, 250, 25, 25, 25, 10, 10, 15] 

経路、すなわち、あります経路1-3、3-4、4-5。

このように、volume_arrayは6x6配列であり、ゼロで構成されています。 volume_arrayの行の値は、各パスの最初の値、すなわち1,3,4に対応します。列の値は、各パスの第2の番号、すなわち3,4,5に対応する。

ここでトリッキーなビットが来ます! vol_listの値がvolume_arrayに追加さtri_numsの各値について

  1. 次のようvol_list

    値は、前述の配列項目に割り当てられています。この配列内の行の値は、パスの最初の値、つまり[4]によって定義され、列の値はパスの2番目の値によって定義されます([4]の場合は[5]を意味します)。

  2. の場合、値10が、volume_array[4][5]に1回、volume_array[3][4]に1回、volume_array[1][3]に1回、3回追加されます。
  3. tri_nums[1]の場合、値15が2回、volume_array[4][5]に1回、volume_array[3][4]に1回加算されます。
  4. tri_nums[2]については、25の値がvolume_array[4][5]に1回加算されます。
  5. 最後に、前の3つのステップで生成された配列のすべての値が加算され、final_arrayが得られます。

言及する価値のある別のことは、tri_numsの合計がlen(vol_list)に等しいということです。さらにtri_nums[n]は常に>tri_nums[n+1]です。

pathtri_numのコードとvol_listのコードを実装するのが理想です。何百ものアイテムがあります。私が今使っている方法は、手で何百ものループを作る必要があることを意味します。 whileループを同時に動作させるにはどうすれば "何百回ものループ"シナリオを回避できますか?

すべてがうまく動作しているが、最終的な出力は、(25)であるvol_listの最終値がarray_list[4][5]に割り当てられていないので、final_arrayではなかったしたことを意味

[[ 0. 0. 0. 0. 0. 0.] 
[ 0. 0. 0. 10. 0. 0.] 
[ 0. 0. 0. 0. 0. 0.] 
[ 0. 0. 0. 0. 25. 0.] 
[ 0. 0. 0. 0. 0. 25.] 
[ 0. 0. 0. 0. 0. 0.]] 

。もう1つのループを実行するだけで済みますが、最後のループを実行する方法はわかりません。

不明な点がある場合は教えてください。

おかげ

+1

'list'はデータ型です。変数名として使用しないでください(名前を変更してください)。 'count <1:'は削除しても同じ結果になるので冗長です。それは、後で複数回反復したい場合にのみ、それを残すことが理にかなっています。 – jDo

+0

何か手で行うことができますが、コンピュータを持つことができます。あなたはそれを手で行うために必要なステップについて考えてみてください。それから、コンピュータにそれをさせてください。コンピュータをそれにするのは難しい場合もありますが、YMMVです。 –

+0

あなたが尋ねたので、コードサンプルは少し長いですし、説明もやや複雑です。私はあなたが記述の部分をコードの対応する部分に散在させるならば、より明確な質問をすると思います。カップルの場所にサンプル出力を追加するとさらに助けになります。それが言われている、私はあなたの何をやっているのかを知っている。私が答えを出すことができるかどうか見てみましょう。 –

答えて

1

あなたは配列の最後の要素を欠場理由は、あなたがtri_numsのオフ要素をポップしていると同時に、nをインクリメントしていることです。あなたは0でnを維持し、(while len(tri_nums) > 0に相当します)あなたの条件while tri_numsをしなければならないのいずれか

iteration n tri_nums n <= len(tri_nums) 
0   0 [3, 2, 1] True 
1   1 [2, 1]  True 
2   2 [1]   False 

、またはおそらくより良い:あなたのwhileループの各反復の初めにntri_numsの値を見てくださいtri_numsの変更を避けて、forのループを使用するだけです。だけなので同じように、tri_numsのたびに一部を反復処理するには、その後、内側のループを変更する必要があります:言われていること

for n in xrange(len(tri_nums)): 
    for num in tri_nums[n:]: 

、複数のアレイを作成し、リストを反復処理し、それらをすべて合算の全体的なアプローチ非常に非効率的です。これはCode Reviewではないので、私はすべての非効率に得ることはありませんが、私は言及したいと思いますいくつかの重要なものがあります

  • あなたが活用することができ、あなたの入力データ構造の多くを持っています
  • のあなたはできるだけ
  • として、あなたが最初に数字を追加し、端部のみ
  • で配列を作成することができますので、あなたは、同じ指標で数値を入れておく代わりに、ネイティブのPython操作のnumpyのベクトル化操作を使用するようにしてください

これを念頭に置いて、私はvol_listにはそれぞれの各番号のみが含まれるようにコードを変更することをおすすめします。

vol_list = [10, 15, 25] 

次に、数字を最初に追加し、結果の合計を配列に貼り付けることで、必要な配列を作成できます。 numpyのは、便利な配列の部分和を計算するcumsum機能が含まれます。

>>> np.cumsum([10, 15, 25]) 
array([10, 25, 50]) 

をし、それがそのインデックス操作で、一度に多くの値を指定することができます。だから、あなたの全体のアルゴリズムはこれまで低減することができる:あなたのメモリ要件は、長いリストのために問題となる場合

final_array = np.zeros((6, 6)) 
final_array[paths[:-1], paths[1:]] = np.cumsum(vol_list) 

、あなたの代わりに通常のnumpyのアレイを、ストレージにScipy's sparse matricesを使用する場合があります。

+0

これは信じられないほどです。私はそれがより大きなデータセットのために働くことを二重チェックしていますが、それほど良いことはありません。あなたは、ウィザードと学者です。 –

+0

助けてくれてうれしいですが、最初に質問を理解するのがいかに難しいかを覚えておいて、あなたの将来の質問を改善するためにそれを使うことを願っています。私はあなたのコードがどのように動作するかを記述する際に、より注意深く立つことができると思います。将来の読者にもう一度あなたの質問をきれいにすることも役に立つでしょう。 (そして、私の答えがあなたの問題を解決した場合、緑のチェックマークをクリックすることでそれを受け入れることは素晴らしいでしょう。) –

関連する問題