Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用类实例替换数组中的元素_Python_Numpy - Fatal编程技术网

Python 用类实例替换数组中的元素

Python 用类实例替换数组中的元素,python,numpy,Python,Numpy,这是类似的,所以请阅读它首先了解我正在试图做什么 现在,我想在有类实例时进行替换。类似于: import numpy as np class B(): def __init__(self, a,b): self.a = a self.b = b arr = np.array([ [1,2,3,4,5],[6,7,8,9,10] ]) b1 = np.array([B(100,'a'), B(11,'b'),

这是类似的,所以请阅读它首先了解我正在试图做什么

现在,我想在有类实例时进行替换。类似于:

import numpy as np

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


arr = np.array([ [1,2,3,4,5],[6,7,8,9,10] ])

b1 = np.array([B(100,'a'),
               B(11,'b'),
               B(300,'c'),
               B(33,'d')])

b2 = np.array([B(45,'a'),
              B(65,'b'),
              B(77,'c'),
              B(88,'d')])

# My d array will be like that and I will have to 
# run 3 loops as below . I can't change that
d = np.array([[b1],[b2]],dtype=object)

# Replace the elements
for i in d:
    for y in i:
        for idx,el in enumerate(y): 
            #y[idx].a = arr.reshape(-1,5) # 5 is the size of every sublength of arr
            #print(y[idx].a)
            pass

# Show the updated values
for i in d:       
    for y in i:
        for idx,x in enumerate(y):
            print(y[idx].a)
我不能使用
b=arr.reforme(-1,a.size)
,因为这必须在循环之外运行。但是,正如我所说的
b
数组将是
y[idx]。值
,因此我不能将它放在第三个循环中,因为我将获得错误的结果,我也不能将它放在第三个循环之外,因为我将无法访问类实例的
部分

我希望我的结果是:

b1 = np.array([B(1,'a'),
               B(2,'b'),
               B(3,'c'),
               B(4,'d'),
               B(5,'d')])

b2 = np.array([B(6,'a'),
              B(7,'b'),
              B(8,'c'),
              B(9,'d'),
              B(10,'d')])
因此,我只想填充
a
部分,例如B类实例。 请注意,与前面的问题一样,
B
被扩展以保存
arr
中的所有5个值

简单地说,检查
arr
的每个子列表的长度(现在是5), 并相应地更新
d
值。因此,如果
b1
b2
有4个值,它们必须成为5个值(前5个值来自
arr
,后5个值来自
arr

print(d.shape)
print(d)
得到

2249:~/mypy$ python3 stack42283851.py 
(2, 1, 4)
[[[<__main__.B object at 0xb71d760c> <__main__.B object at 0xb71d7aac>
   <__main__.B object at 0xb71d7acc> <__main__.B object at 0xb71e5cec>]]

 [[<__main__.B object at 0xb391718c> <__main__.B object at 0xb39171ac>
   <__main__.B object at 0xb39171cc> <__main__.B object at 0xb39171ec>]]]
添加

import itertools
for a,b in itertools.zip_longest(arr[0,:],b1):
     print(a,b)
产生

1 B(100, a)
2 B(11, b)
3 B(300, c)
4 B(33, d)
5 None
[B(1, a) B(2, b) B(3, c) B(4, d) B(5, d)]
[B(1, a) B(2, b) B(None, c) B(None, d)]
将其更改为:

newlist = []
for a,b in itertools.zip_longest(arr[0,:],b1):
    if b is not None:
        new_b = B(a, b.b)
        last_b = b
    else:
        new_b = B(a, last_b.b)
    newlist.append(new_b)
print(np.array(newlist))
产生

1 B(100, a)
2 B(11, b)
3 B(300, c)
4 B(33, d)
5 None
[B(1, a) B(2, b) B(3, c) B(4, d) B(5, d)]
[B(1, a) B(2, b) B(None, c) B(None, d)]
将其分配给
b1
,并对
a[1,:]
b2
重复该操作

为了更简洁一点,我可以将
new_b
代码作为函数编写,并将循环重写为列表

是的,我可以就地修改
b
,例如

b.a = a
但是既然我需要创建一个新的
B
对象来替换
None
,为什么还要麻烦呢。我无法将新的
B
对象添加到原始
b1
数组中。因此,通过列表创建新数组更简单


我可以通过以下方式对
d
b1
进行就地更改:

def replace(a,b):
    b.a = a
f = np.frompyfunc(replace, 2, 1)
f(arr[:,None,:4], d)      # produces array of None; ignore
print(d)
print(b1)

[[[B(1, a) B(2, b) B(3, c) B(4, d)]]  # chgd d

[[B(6, a) B(7, b) B(8, c) B(9, d)]]]
[B(1, a) B(2, b) B(3, c) B(4, d)]    # chgd b1
我只是用
frompyfunc
作为一种懒人的方式,对
d
广播
arr
,并迭代所有元素。请注意,我必须更改
arr
以匹配
d
形状。此外,这不会添加任何新的
B()
。显然,你不能在适当的地方这样做


我的
B

class B():
    def __init__(self, a,b):
        self.a = a
        self.b = b
    def __repr__(self):
        return 'B(%s, %s)'%(self.a, self.b)

玩Pyfunc的
游戏
更多:

getB_b = np.frompyfunc(lambda x: x.b, 1,1)   # fetch b attributes
print(getB_b(d))
#[[['a' 'b' 'c' 'd']]
#
# [['a' 'b' 'c' 'd']]]

mkB = np.frompyfunc(B, 2,1)   # build array of B() with broadcasting
print(mkB(arr, ['a','b','c','d','e']))
# [[B(1, a) B(2, b) B(3, c) B(4, d) B(5, e)]
#  [B(6, a) B(7, b) B(8, c) B(9, d) B(10, e)]]

print(mkB(arr[:,:4], getB_b(d[:,0,:])))
# [[B(1, a) B(2, b) B(3, c) B(4, d)]
#  [B(6, a) B(7, b) B(8, c) B(9, d)]]

编辑评论

arr1 = np.array([ [1,2],[6,7] ])
newlist = []
for a,b in itertools.zip_longest(arr1[0,:],b1):
    if b is not None:
        new_b = B(a, b.b)
        last_b = b
    else:
        new_b = B(a, last_b.b)
    newlist.append(new_b)
print(np.array(newlist))
产生

1 B(100, a)
2 B(11, b)
3 B(300, c)
4 B(33, d)
5 None
[B(1, a) B(2, b) B(3, c) B(4, d) B(5, d)]
[B(1, a) B(2, b) B(None, c) B(None, d)]
arr
较短时,
a
None
(而不是
b
);所以我们需要对此进行测试

def foo(arr,bn):
    newlist = []
    for a,b in itertools.zip_longest(arr,bn):
        print(a,b)
        if a is None:
            pass
        else:
            if b is not None:
                new_b = B(a, b.b)
                last_b = b
            else:
                new_b = B(a, last_b.b)
            newlist.append(new_b)
    return newlist
print(np.array(foo(arr1[0,:],b1)))  # arr1 shorter
print(np.array(foo(arr[0,:], b2)))  # arr longer 
测试:

1 B(1, a)
2 B(2, b)
None B(3, c)
None B(4, d)
[B(1, a) B(2, b)]

1 B(6, a)
2 B(7, b)
3 B(8, c)
4 B(9, d)
5 None
[B(1, a) B(2, b) B(3, c) B(4, d) B(5, d)]

没有什么特别或神奇的;只要确保我得到了正确的
if
测试和缩进就行了。

这样做替换块。另外请注意,这假设您的arr严格以5的倍数表示,并且将有与示例中给出的arr中的块一样多的块,如b1、b2等

for i,b_arr in enumerate(d):
    temp_arr = []
    for j in range(5):
        if j<len(b_arr)
            temp_arr.append(B(arr[i,j],b_arr[j].b))
        else:
            temp_arr.append(B(arr[i,j],b_arr[-1].b))
     d[i] = np.array(temp_arr) ## not sure if this step is right, not too familiar with numpy.
对于枚举(d)中的i,b_arr:
温度_arr=[]
对于范围(5)内的j:

如果是这样,有没有办法使用
d
而不是重复2次?一个用于
b1
,一个用于
b2
?第二,如果我想替换b类的b字段,我将使用新的_b=b(a,b)?那么
itertools.zip_longest()
呢?我必须放置另一个数组来保存
b
值。因此,从一开始就重新运行整个循环?我还没有测试它是否以相反的方式工作。如果,我们需要从B中减去元素,而不是添加(在len(a[0])和len(a[1])的情况下)小于4对于这个示例,我添加了两个函数,使对
B的数组的操作更容易。您好,感谢您的解决方案。我正在使用itertools的方法。有两件事。1)当len(arr[0])temp\u arr.append(B)中的
numpy.ndarray'对象没有属性“B”
)(arr[i,j],b_arr[j].b))