2017-01-12 6 views
2

を反復:のpython:私は様々なnumpyの配列の次のリストを持っているパラレルネストされたリスト内のすべてのアイテムを通じて

nparrays_list = [ 
    array([1, 2, 3, 4]) 
    array([5, 6, 7, 8]), 
    array([9, 10, 11, 12]) 
] 

私は(つまり、Iドン」リストの形状に影響を与えることなく、リスト全体を反復処理したいですトンnumpyの配列の次のリストを取得するために)リストを平らにしたい:

import numpy as np 

nparrays_list_Decimal = [] 
for nparray in nparrays_list: 
    nparray_Decimal = np.array([D(str(item)) for item in nparray]) 
    nparrays_list_Decimal.append(nparray_Decimal) 

nparrays_list_Decimal = [ 
    array([Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')]) 
    array([Decimal('5'), Decimal('6'), Decimal('7'), Decimal('8')]), 
    array([Decimal('9'), Decimal('10'), Decimal('11'), Decimal('12')]) 
] 

ここで私がこれまで持っているコードです

私の問題は、大量のデータを扱っているため、新しいリストを作成するのが理想的ではないということです。無駄な記憶)。アイテムがネストされたリスト(この場合numpy配列)であっても、元のリストのすべてのアイテムを繰り返し処理する簡単な方法はありますか?

+1

'D 'をどのように定義しましたか?そしてなぜ 'nparrays_list'がnumpy配列ではないのですか? – Kasramvd

+0

私はあなたが少なくとも "U8"形式とジェネレータを渡すことで一時的なリストを保存できると思います。それはあなたの項目を8文字に切り詰めるでしょう。 –

+0

'D'はDecimalを表します。より明確にするためにそれを編集しましょう。 numpl配列のリストなので、 'nparrays_list'です。コンテナをnparrayにする必要はありません –

答えて

1

を試してみてください

>>> arr=np.array([1,2,3]) 
>>> arr 
array([1, 2, 3]) 
>>> arr[1]="string" 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: invalid literal for long() with base 10: 'string' 
:numpyの配列内のオブジェクトの種類を借り、あなたは(彼らは dtype=objectの配列がある場合を除く)。ここ

はあなたがnumpyの配列に混合型を持つことができないという事実のデモで新しいアレイを作成する必要があります

Decimal型をintの配列に代入しても、その要素は配列の小数点以下の型に変更されません。 arr[1]Decimalに変換したが、その後静かにint型に逆変換されています

>>> arr 
array([1, 2, 3]) 
>>> arr[1]=Decimal(arr[1]) 
>>> arr 
array([1, 2, 3]) 
>>> type(arr[1]) 
<type 'numpy.int64'> 

あなたが行うことができます。

>>> nparrays_list_Decimal=[np.array([Decimal(e) for e in arr]) for arr in nparrays_list] 
>>> nparrays_list_Decimal 
[array([Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')], dtype=object), array([Decimal('5'), Decimal('6'), Decimal('7'), Decimal('8')], dtype=object), array([Decimal('9'), Decimal('10'), Decimal('11'), Decimal('12')], dtype=object)] 

それとも、単にリストのリストに固執する:

>>> LoL=[[Decimal(e) for e in arr] for arr in nparrays_list] 
>>> LoL 
[[Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')], [Decimal('5'), Decimal('6'), Decimal('7'), Decimal('8')], [Decimal('9'), Decimal('10'), Decimal('11'), Decimal('12')]] 

メモリが問題になる場合は、通常、あなたがそれらを変換すると、あなたがサブアレイを削除することによって、より多くのメモリ効率的な変換を行うことができます)ささやかな配列で、それについてはあまり心配する必要はありませんND:

from collections import deque 

nparrays_list=deque(LoA) # the List of Arrays is garbage collected.. 
nparrays_list_Decimal=[] 
while nparrays_list: 
    # each sublist is garbage collected after being popped and iterated 
    nparrays_list_Decimal.append(np.array([Decimal(e) for e in nparrays_list.popleft()])) 

>>> nparrays_list_Decimal 
[array([Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')], dtype=object), array([Decimal('5'), Decimal('6'), Decimal('7'), Decimal('8')], dtype=object), array([Decimal('9'), Decimal('10'), Decimal('11'), Decimal('12')], dtype=object)] 
+0

リストの理解で十分です。ありがとう。あなたのポストとhpauljのポストに基づいて、ここではメモリが制限要因ではないように思えます。 –

0

すべての項目を反復処理するには、このように入れ子のforループを実行できます。

たぶん
nparrays_list = [ 
     array([1, 2, 3, 4]), 
     array([5, 6, 7, 8]), 
     array([9, 10, 11, 12]) 
    ] 

for arr in nparrays_list: 
    for i, item in enumerate(arr): 
    arr[i] = Decimal(str(item)) 
+0

最後の行で 'item = Decimal(str(item))'を試しても何も起こりません。これを使ってすべての値をDecimalオブジェクトに変換できますか? –

+0

@ jcmetz21これについての私の答えを更新 – gipsy

+0

これは要素を 'Decimal'オブジェクトに変換しません。 hpauljの投稿または私の投稿を参照してください。 – dawg

1

この

import numpy as np 

nparrays_list_Decimal = [list(map(float, lst)) for lst in nparrays_list] 

編集のようなもの:小数を使用するには

From the Python Documentation on Decimals

あなたはdiffeを持つことになりますので、この

from decimal import * 
nparrays_list_Decimal = [list(map(Decimal, lst)) for lst in nparrays_list] 
+0

これを使用して数値をDecimalオブジェクトに変換するにはどうすればよいですか?浮動小数点数が不正確です –

+1

小数点コードが追加されました –

1
nparrays_list = [ 
    array([1, 2, 3, 4]) 
    array([5, 6, 7, 8]), 
    array([9, 10, 11, 12]) 
] 

ことについて心配しないでください新しいリスト。リストには、メモリ内の他の場所にあるオブジェクトへのポインタが含まれています。この場合、リストは3つの整数のメモリしか占有しません。これらのコンポーネントはメモリを占有します。これらは4要素のデータバッファを持つ配列です。

nparrays_list_Decimal = [ 
    array([Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')]), 
    array([Decimal('5'), Decimal('6'), Decimal('7'), Decimal('8')]), 
    array([Decimal('9'), Decimal('10'), Decimal('11'), Decimal('12')]) 
] 

は、3つのポインタを持つ別の小さなリストです。それらのポインタを元のnparray_listに戻すことができますが、なぜですか? 3つの整数分のスペースを節約するだけですか?

しかし、どのような重要なのですが、新しい配列がオリジナルで、互換性、メモリ賢明ではないということです。

array([Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')]) 

は、オブジェクトDTYPE配列です。これはリストのようなもので、メモリ内のどこか他のオブジェクトであるDecimal(n')オブジェクトへのポインタです。それは新しい配列でなければなりません。元のarray([1,2,3,4])np.int32アイテムを置き換えることはできません。換言すれば、

nparrays_list_Decimal = [ 
    [Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')], 
    [Decimal('5'), Decimal('6'), Decimal('7'), Decimal('8')], 
    [Decimal('9'), Decimal('10'), Decimal('11'), Decimal('12')] 
] 

リストのリストに固執:

は、なぜあなたはちょうど

nparrays_list = [ 
    [1, 2, 3, 4], 
    [5, 6, 7, 8], 
    [9, 10, 11, 12] 
] 

からに行っていません。 Decimalオブジェクトの配列は、同じもののリストよりも便利ですか?

===============

Decimalは、多くの数学演算を規定するので、Decimalオブジェクトの配列にいくつかの配列演算を行うことが可能である:

In [482]: arr = np.array([Decimal(i) for i in range(1,4)]) 
In [483]: arr 
Out[483]: array([Decimal('1'), Decimal('2'), Decimal('3')], dtype=object) 
In [484]: arr + 1 
Out[484]: array([Decimal('2'), Decimal('3'), Decimal('4')], dtype=object) 
In [485]: 1/arr 
Out[485]: 
array([Decimal('1'), Decimal('0.5'), 
     Decimal('0.3333333333333333333333333333')], dtype=object) 
それは 1/np.arange(1,4)よりも遅くなります

np.array([1/i for i in arr]) 

:この最後の文Speedwise

は基本的に同じです。

====================

あなたは10進配列を作ることによって少し速度向上を得る可能性があります:

In [503]: np.frompyfunc(Decimal,1,1)(np.arange(3)) 
Out[503]: array([Decimal('0'), Decimal('1'), Decimal('2')], dtype=object) 
In [504]: np.frompyfunc(Decimal,1,1)(np.arange(12).reshape(3,4)) 
Out[504]: 
array([[Decimal('0'), Decimal('1'), Decimal('2'), Decimal('3')], 
     [Decimal('4'), Decimal('5'), Decimal('6'), Decimal('7')], 
     [Decimal('8'), Decimal('9'), Decimal('10'), Decimal('11')]], dtype=object) 

で他のテスト私はfrompyfuncが明示的な反復式よりも適度な(例えば2倍の)速度向上を持つことを発見しました。また、多次元配列をシームレスに処理できるという利点もあります。配列objectを返します。時にはそれは問題です。ここでそれはちょうどいいです。

In [509]: timeit np.frompyfunc(Decimal,1,1)(np.arange(2000)) 
1000 loops, best of 3: 752 µs per loop 
In [510]: timeit np.array([Decimal(str(i)) for i in np.arange(2000)]) 
100 loops, best of 3: 17.1 ms per loop 
In [515]: timeit np.array([Decimal(i) for i in range(2000)]) 
100 loops, best of 3: 7.39 ms per loop 
In [525]: timeit np.array([Decimal(i.item()) for i in np.arange(2000)]) 
100 loops, best of 3: 11.3 ms per loop 

私はなぜstr(i)を使用したのだろうと思いました。しかし、その後私はDecimalnp.dtypesnp.int32ではない)のうちのいくつかしか取ることができないことが分かった。私の推測では、frompyfuncはPythonのスカラーを生成するためにitem()または同等のものを使用している:

In [523]: np.frompyfunc(Decimal,1,1)(np.arange(2)) 
Out[523]: array([Decimal('0'), Decimal('1')], dtype=object) 
In [524]: np.array([Decimal(i.item()) for i in np.arange(2)]) 
Out[524]: array([Decimal('0'), Decimal('1')], dtype=object) 

frompyfuncnp.int32オブジェクトからPythonのスカラーを生成するi.item()と同等のものをやっている必要があります。

+0

numpyモジュールではるかに簡単にできる数学演算を実行しているので、np.arrayコンテナが必要です。 –

+0

はい、オブジェクト配列の使用が便利ないくつかの例を追加しました。いずれにせよ、私はあなたがスピードやメモリ使用を改善できるとは思わない。コンテナの構造にかかわらず、1000年代の 'Decimal'オブジェクトとそれらのオブジェクトへのポインタの1000を持っています。 – hpaulj

+0

'frompyfunc'を使って' Decimal'配列作成を容易にするデモンストレーションを追加しました。 – hpaulj

0

私はnumpyを持っていないが、以下はあなたの問題を解決するためにいくつかの方向性を与えることがあります。

Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 08:06:12) [MSC v.1900 64 bit (AMD64)] on win32 
Type "copyright", "credits" or "license()" for more information. 
>>> import array 
>>> array_list = [ 
    array.array('q', [1, 2, 3, 4]), 
    array.array('q', [5, 6, 7, 8]), 
    array.array('q', [9, 10, 11, 12]) 
    ] 
>>> def iterate(iterable): 
    for index_a, value_a in enumerate(iterable): 
     try: 
      for index_b, value_b in iterate(value_a): 
       yield [index_a] + index_b, value_b 
     except TypeError: 
      yield [index_a], value_a 


>>> for index, value in iterate(array_list): 
    print(value, 'is at', index) 


1 is at [0, 0] 
2 is at [0, 1] 
3 is at [0, 2] 
4 is at [0, 3] 
5 is at [1, 0] 
6 is at [1, 1] 
7 is at [1, 2] 
8 is at [1, 3] 
9 is at [2, 0] 
10 is at [2, 1] 
11 is at [2, 2] 
12 is at [2, 3] 
>>> 

あなたの問題への解決策を完了するために、自動キャストまたは型の変換がサポートすることができます。

>>> def iterate(iterable, cast): 
    for index_a, value_a in enumerate(iterable): 
     try: 
      for index_b, value_b in iterate(value_a, cast): 
       yield [index_a] + index_b, value_b 
     except TypeError: 
      yield [index_a], cast(value_a) 


>>> import decimal 
>>> for index, value in iterate(array_list, decimal.Decimal): 
    print(repr(value), 'came from', index) 


Decimal('1') came from [0, 0] 
Decimal('2') came from [0, 1] 
Decimal('3') came from [0, 2] 
Decimal('4') came from [0, 3] 
Decimal('5') came from [1, 0] 
Decimal('6') came from [1, 1] 
Decimal('7') came from [1, 2] 
Decimal('8') came from [1, 3] 
Decimal('9') came from [2, 0] 
Decimal('10') came from [2, 1] 
Decimal('11') came from [2, 2] 
Decimal('12') came from [2, 3] 
>>> 
+0

私は間違いなくこれらの反復可能な関数を作成する必要があります。ありがとう –

関連する問題