3

別の配列にあるデータをループして操作する他の方法があるかどうかを知りたいです。

import numpy as np

a = np.arange(2)
b = np.arange(5)
c = np.arange(5)

l1 = []
for x in a:
    l2 = []
    for y in b: 
        l3 = []
        y = x + 1  
        for z in c:
            z = x + y
            t = (x,y,z)
            l3.append(t)
        l2.append(l3)
    l1.append(l2) 
print l1
4

3 に答える 3

7

このコードは、まさにあなたがしていることを行います。

def method(lst, range1, range2):
    for i in lst:
        yield [[(i, i+1, 1+(i*2))]*range2]*range1

ジェネレータ式に変換することもできます:

def gen_method(lst, r1, r2):
    return ([[(i, i+1, 1+(i*2))]*r2]*r1 for i in lst)

必要に応じて、自分でテストしてください。


私のテスト:

a = range(2)
b = range(5)
c = range(5)

def your_method(a, b, c):
    l1 = []
    for x in a:
        l2 = []
        for y in b: 
            l3 = []
            y = x + 1  
            for z in c:
                z = x + y
                t = (x,y,z)
                l3.append(t)
            l2.append(l3)
        l1.append(l2)
    return l1

def my_method(lst, range1, range2):
    for i in lst:
        yield [[(i, i+1, 1+(i*2))]*range2]*range1

yours = your_method(a, b, c)
mine = list(my_method(a, len(b), len(c)))

print yours
print '==='
print mine
print '==='
print yours == mine

>>> 
[[[(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)]], [[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)]]]
===
[[[(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)], [(0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1), (0, 1, 1)]], [[(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)], [(1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3), (1, 2, 3)]]]
===
True
于 2013-04-08T07:26:42.063 に答える
1

さて、リスト内包表記を使用してコードを圧縮できます。

[[[(x,x+1,x*2 +1)]*len(c)]*len(b) for x in a]

これが行うことは、a のすべての x に対してループし、要素のリストを作成することです。ここで、各要素は b のすべての y に対して生成されたリストであり、そのリストの各要素は(x,x+1,2*x+1)c のすべての z に対して生成されます。

于 2013-04-08T07:43:32.243 に答える
0

別のアプローチは、 を使用itertoolsし、結果のリストを に変換しnumpy arrayて再形成することです

import numpy as np
import itertools as it

a = np.arange(2)
b = np.arange(5)
c = np.arange(5)

l1 = np.array([(i, i+1, i*2+1) for i, rb, rb in it.product(a, b, c)])
l1 = l1.reshape(len(a), len(b), len(c), len(d[0]))

これは、サイズが大きくなるにつれて他のすべてのアプローチよりも多くのメモリを消費する可能性がありますが、2 行だけであり、同じオブジェクトへの複数のポインターを作成するだけでなく、各トリプレットに一意の要素を作成します。

編集

リストとしてトリプレット (i、i+1、i*1+1) を保持することもできる別の方法は次のとおりです。

l1 = np.empty([len(a), len(b), len(c)], dtype=object)
for i, rb, rb in it.product(a, b, c):
    l1[i,ra, rb] = (i, i+1, i*2+1)
于 2013-04-08T13:38:04.280 に答える