python - 用将索引作为参数的对象填充 2d numpy 数组
问题描述
想象一下这样的课程。
class Foo:
def __init__(self,y,x):
self.y = y
self.x = x
然后我有一个数组
obj_arr = np.zeros((200,200), dtype=object)
我想用完整的类填充它,但输入参数作为数组的索引。
我玩弄了 np.where 的想法,但看不到如何添加参数。
np.where(obj_arr == None, obj_arr, Foo())
目前我正在做这个令人作呕的嵌套循环。1)我知道它不是正确的方法 2)它需要永远。
for y in range(obj_arr.shape[0]):
for x in range(obj_arr.shape[1]):
obj_arr[y,x] == Foo(y,x)
在我发疯之前,请有人把我推向正确的方向。
解决方案
class Foo:
def __init__(self, y, x):
self.y = y
self.x = x
def __repr__(self):
return f'Foo({self.y}, {self.x})'
In [69]: Foo(1,2)
Out[69]: Foo(1, 2)
建议的nditer
解决方案:
def foo1(n):
a = np.empty((n,n), dtype=object)
with np.nditer(a, flags=['multi_index', 'refs_ok'], op_flags=['writeonly']) as it:
for x in it:
x[...] = Foo(it.multi_index[1], it.multi_index[0])
return a
In [70]: foo1(2)
Out[70]:
array([[Foo(0, 0), Foo(1, 0)],
[Foo(0, 1), Foo(1, 1)]], dtype=object)
嵌套循环:
def foo2(n):
a = np.empty((n,n), dtype=object)
for i in range(n):
for j in range(n):
a[i,j] = Foo(i,j)
return a
In [71]: foo2(2)
Out[71]:
array([[Foo(0, 0), Foo(0, 1)],
[Foo(1, 0), Foo(1, 1)]], dtype=object)
我最喜欢的,frompyfunc
:
def foo3(n):
f = np.frompyfunc(Foo, 2, 1)
I,J = np.meshgrid(np.arange(n),np.arange(n), sparse=True)
return f(I,J)
In [72]: foo3(2)
Out[72]:
array([[Foo(0, 0), Foo(1, 0)],
[Foo(0, 1), Foo(1, 1)]], dtype=object)
时间:
In [73]: timeit foo1(200)
144 ms ± 305 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [74]: timeit foo2(200)
25.7 ms ± 958 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [75]: timeit foo3(200)
17.7 ms ± 40.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
为了比较,嵌套列表:
def foo4(n):
alist = []
for i in range(n):
blist = []
for j in range(n):
blist.append(Foo(i,j))
alist.append(blist)
return alist
In [77]: foo4(2)
Out[77]: [[Foo(0, 0), Foo(0, 1)], [Foo(1, 0), Foo(1, 1)]]
In [78]: timeit foo4(200)
18.6 ms ± 149 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
推荐阅读
- javascript - 如何禁用 safari ios 13 的缩放和缩小?(在我的网页中)
- symfony - 学说嵌套 AND OR 查询
- c++ - 为什么编译器找不到类 std::ifstream?
- java - 如何让 Desktop.getDesktop().open() 和 Runtime.getRuntime().exec() 从 Tomcat 下的 servlet 工作?
- java - 从java存储过程调用main函数
- flutter - 从 JSON 文件中获取数据时遇到范围错误
- apache-spark - 火花表操作 - 列值到行和行值转置
- android - 指定为非 null 的参数为 null - 在 Kotlin 中加载图像
- php - 如何检查是否是第一次在 foreach 迭代中的 if 语句中找到值
- python - 使用 ansible 和 python3 在 ubuntu 上安装 docker