从数组数组中访问元素,调用函数来执行数组数组

时间:2017-02-06 12:07:53

标签: python numpy

如果我有一个类似的数组:

a = np.array([ [A(2,3 , np.array([[C(2,3)], [C(5,6)] ]))],
               [A(4,5 , np.array([[C(1,2)],[C(9,7)]]))]
             ])

对于其他类实例,我如何访问所有元素?

例如,

for idx,x in np.ndenumerate(a):

    print('Index :{0}'.format(idx))
    print('Elmt:  {0}'.format(x.the_c[idx].t))

返回:

Index :(0, 0)
Elmt: 2
Index :(1, 0)
Elmt: 9

因此只有2个指数和2个元素而不是4个。

通常,我必须拨打另一个ndenumerate,但我不确定如何调用它或者是否有更好(更有效)的方式。

代码:

import numpy as np

class A():
    def __init__(self, a, b,the_c):
        self.a = a
        self.b = b
        self.the_c = the_c

    def methodA(self):
        return self.the_c


class B():

    def __init__(self, c, d, the_a):
        self.c = c
        self.d = d
        self.the_a = the_a

    def evaluate(self):
        for idx, x in np.ndenumerate(self.the_a):
            x.methodA()
            return x.the_c

class C():
    def __init__(self,t,y):
        self.t = t
        self.y = y

如果我想通过调用函数来评估a数组,我该如何调用它?

def evaluate(self):
    for idx, x in np.ndenumerate(self.the_a):
        x.methodA()
        return x.the_c

OR

def evaluate(self):
      for idx, x in np.ndenumerate(self.the_a):

           the_inst = A(x.a, x.b, x.self.the_c)
           the_inst.methodA()
           return the_inst.the_c

因此,B类中的evaluate方法将是唯一被调用的方法,它将执行包含许多C实例的许多A实例。

a = np.array([ [A(2,3 , np.array([[C(2,3)], [C(5,6)] ]))],
               [A(4,5 , np.array([[C(1,2)],[C(9,7)]]))]
             ])
b = B(1,2,a).evaluate()

for idx, x in np.ndenumerate(b):
    print(x.t)

提供2 and 5而不是2,5,1,9

2 个答案:

答案 0 :(得分:2)

a是包含2个对象的2x1数组,类A

In [162]: a
Out[162]: 
array([[<__main__.A object at 0xab20030c>],
       [<__main__.A object at 0xab20034c>]], dtype=object)

我可以将方法调用转换为函数:

def foo(an_A):
     return an_A.methodA()

In [164]: a.shape
Out[164]: (2, 1)
In [165]: foo(a[0,0])
Out[165]: 
array([[<__main__.C object at 0xab2001cc>],
       [<__main__.C object at 0xab2002ec>]], dtype=object)

这是另一个2x1数组,这次包含C个对象。有没有特别的理由为什么这些都是(2,1)而不是(2,)?

frompyfunc是一个方便的工具,用于将函数应用于任何数组的所有元素,尤其是当输入和输出都是对象数组时:

In [166]: f=np.frompyfunc(foo,1,1)
In [167]: f(a)
Out[167]: 
array([[ array([[<__main__.C object at 0xab2001cc>],
       [<__main__.C object at 0xab2002ec>]], dtype=object)],
       [ array([[<__main__.C object at 0xab20096c>],
       [<__main__.C object at 0xab2003cc>]], dtype=object)]], dtype=object)

a类似,这是(2,1),但现在它包含2(2,1)C数组。

我可以使用。

将其转换为{4}个C对象数组
In [176]: np.concatenate(f(a)[:,0])
Out[176]: 
array([[<__main__.C object at 0xab2001cc>],
       [<__main__.C object at 0xab2002ec>],
       [<__main__.C object at 0xab20096c>],
       [<__main__.C object at 0xab2003cc>]], dtype=object)

np.r_[tuple(f(a)[:,0])]也是这样做的。 https://stackoverflow.com/a/42091616/901925

我们可以将连接应用于(2,1)f(a)数组,但结果更加混乱。

您还可以使用ndenumerate生成与f(a)相同的内容。首先,您需要创建一个将接收单个foo(x)结果的数组:

In [186]: res=np.empty(a.shape, object)
In [187]: for idx,x in np.ndenumerate(a):
     ...:     res[idx] = foo(x)
     ...:     
In [188]: res
Out[188]: 
array([[ array([[<__main__.C object at 0xab2001cc>],
       [<__main__.C object at 0xab2002ec>]], dtype=object)],
       [ array([[<__main__.C object at 0xab20096c>],
       [<__main__.C object at 0xab2003cc>]], dtype=object)]], dtype=object)

在1d aa[:,0]上,我们可以使用简单的列表理解:

In [189]: [foo(x) for x in a[:,0]]
Out[189]: 
[array([[<__main__.C object at 0xab2001cc>],
        [<__main__.C object at 0xab2002ec>]], dtype=object),
 array([[<__main__.C object at 0xab20096c>],
        [<__main__.C object at 0xab2003cc>]], dtype=object)]
In [190]: np.array([foo(x) for x in a[:,0]])
Out[190]: 
array([[[<__main__.C object at 0xab2001cc>],
        [<__main__.C object at 0xab2002ec>]],

       [[<__main__.C object at 0xab20096c>],
        [<__main__.C object at 0xab2003cc>]]], dtype=object)
In [191]: _.shape
Out[191]: (2, 2, 1)

我很想回去制作foo返回an_A.method()[:,0],或简化a

In [192]: a1 = np.array([ A(2,3 , np.array([C(2,3), C(5,6) ])),
     ...:                A(4,5 , np.array([C(1,2),C(9,7)]))
     ...:              ])
In [195]: np.array([foo(x) for x in a1])    # (2,2) result
Out[195]: 
array([[<__main__.C object at 0xab1aefcc>,
        <__main__.C object at 0xab1ae94c>],
       [<__main__.C object at 0xab1ae0cc>,
        <__main__.C object at 0xab1eb2ac>]], dtype=object)

如果我提供课程repr方法

def __repr__(self):
    return 'A<{0.a},{0.b},{0.the_c}>'.format(self)
def __repr__(self):
    return 'C<{0.t},{0.y}>'.format(self)

然后a显示为

array([[A<2,3,[[C<2,3>]
 [C<5,6>]]>],
       [A<4,5,[[C<1,2>]
 [C<9,7>]]>]], dtype=object)

f(a)

[[array([[C<2,3>],
       [C<5,6>]], dtype=object)]
 [array([[C<1,2>],
       [C<9,7>]], dtype=object)]]

使用B的类似代表,b = B(1,2,a)显示为

B<1,2,[[A<2,3,[[C<2,3>]
 [C<5,6>]]>]
 [A<4,5,[[C<1,2>]
 [C<9,7>]]>]]>

B(1,2,fA(a)).the_a为(相当于使用B.evaluate实施f

[[array([[C<2,3>],
       [C<5,6>]], dtype=object)]
 [array([[C<1,2>],
       [C<9,7>]], dtype=object)]]

答案 1 :(得分:1)

对嵌套结构进行迭代:

for sub in a:
    for c in sub[0].the_c:
        print(c[0].t)

输出:

2
5
1
9