Python空的numpy 2D数组并添加值

huangapple go评论89阅读模式
英文:

Python empty numpy 2D array and append value

问题

问题

我想创建一个大小未定义的2D空numpy数组并追加值。

我的尝试

import numpy as np
import random

unknown = random.randint(2, 666)

#arr = np.array([np.array([])])
#arr = np.empty((unknown, 0), int)

for ch in range (unknown):
    some_input = random.randint(1, 666)
    #arr[ch] = np.append((arr[ch], some_input))
    #arr[ch] = np.concatenate((arr[ch], some_input))
    #arr = np.append((arr, some_input), axis=ch)
    #arr = np.concatenate((arr, some_input), axis=ch)

none of them works.

它们都不起作用。

您可以建议创建轴向数组,然后将它们组合成单个np数组,但我不能这样做。

必须逐个追加值。

如果未知值变大,并且在我们的for循环之外存在多个for循环,那么计算机内存无法处理它。

英文:

Problem

I wanna make size undefined 2D empty numpy array and append values.

my try

import numpy as np
import randrom

unknown = random.randint(2, 666)

#arr = np.array([np.array([])])
#arr = np.empty((unknown, 0), int)


for ch in range (unknown):
    some_input = random.randint(1, 666)
    #arr[ch] = np.append((arr[ch], some_input))
    #arr[ch] = np.concatenate((arr[ch], some_input))
    #arr = np.append((arr, some_input), axis=ch)
    #arr = np.concatenate((arr, some_input), axis=ch)

none of them works.

You may suggest make axis-wise arrays and combined them into single np array but I cannot do that.

the values must be appended by one by one.

if the unknown value became big and multiple for loops exist outside our for loop then the computer memory cannot handle it.

答案1

得分: 1

以下是翻译好的内容:

首先尝试一种直接的列表附加方法来构建一个数组。这在最后构建一个数组:

res = []
for i in range(10):
    res.append(np.arange(20))
arr = np.array(res)

数组的形状为:

arr.shape
# 输出: (10, 20)

计时结果如下:

%%timeit
res = []
for i in range(10):
    res.append(np.arange(20))
arr = np.array(res)
# 输出: 29.7 µs ± 73.4 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

现在尝试一种NumPy方法,试图模仿列表,创建一个“空”起始数组,并在每一行添加新数组。注意,我必须仔细匹配维度。这种方法不容忽视:

res = np.zeros((0, 20), int)
for i in range(10):
    res = np.concatenate((res, np.arange(20)[None, :]), axis=0)

数组的形状为:

res.shape
# 输出: (10, 20)

计时结果如下:

%%timeit
res = np.zeros((0, 20), int)
for i in range(10):
    res = np.concatenate((res, np.arange(20)[None, :]), axis=0)
# 输出: 119 µs ± 398 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

这种方法明显慢得多。每次连接(或np.append)都需要完全复制数组。列表设计用于增长,而数组则不是。每次连接都会将一个(n,20)数组和一个(1,20)数组连接在一起,以创建一个新的(n+1,20)数组。数组克隆更难以实现,并且速度较慢。不要这样做。

另一种方法是从一个(10,20)形状的数组开始,并为每一行赋值。最好的方法是使用整个数组方法来创建数组,而无需任何迭代。


一种变体是使用列表推导来制作一个数组列表,并使用一个连接调用将它们连接成一个数组:

np.concatenate([np.arange(20)[None, :] for _ in range(10)], axis=0).shape

数组的形状为:

(10, 20)

计时结果如下:

timeit np.concatenate([np.arange(20)[None, :] for _ in range(10)], axis=0).shape
# 输出: 43.7 µs ± 180 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
英文:

First try a straight forward list append approach to building an array. This does one array build at the end:

In [82]: res=[]
    ...: for i in range(10):
    ...:     res.append(np.arange(20))
    ...: arr = np.array(res)

In [83]: arr.shape
Out[83]: (10, 20)

In [84]: %%timeit
    ...: res=[]
    ...: for i in range(10):
    ...:     res.append(np.arange(20))
    ...: arr = np.array(res)
29.7 µs ± 73.4 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

Now try a numpy approach that tries to immitate the list, making an "empty" start array, and copying it to a new one with each new row. Note that I have to match the dimensions carefully. There's less room for being sloppy with this approach:

In [85]: res = np.zeros((0,20),int)
    ...: for i in range(10):
    ...:     res = np.concatenate((res, np.arange(20)[None,:]), axis=0)
    ...:     

In [86]: res.shape
Out[86]: (10, 20)

In [87]: %%timeit
    ...: res = np.zeros((0,20),int)
    ...: for i in range(10):
    ...:     res = np.concatenate((res, np.arange(20)[None,:]), axis=0)
119 µs ± 398 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

It's quite a bit slower. Each concatenate (or np.append) requires a full array copy. Lists are designed to grow, arrays are not.

Each concatenate joins a (n,20) array and a (1,20) to make a new (n+1, 20) array.

The array clone is harder to get right, and slower. Don't do it.

An alternative is to start off with a (10,20) shape array, and assign each row. Better yet use a mix of whole-array methods to make the array without any itertions.


A variation on the list approach, using a list comprehension to make a list of arrays, and one concatenate call to join them into one:

In [88]: np.concatenate([np.arange(20)[None,:] for _ in range(10)], axis=0).shape
Out[88]: (10, 20)

In [89]: timeit np.concatenate([np.arange(20)[None,:] for _ in range(10)], axis=0).shape
43.7 µs ± 180 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

答案2

得分: 1

如果我理解正确,您想要一个在运行时增长的空数组。假设您附加的数据长度为k,运行n次,您将获得一个n x k的矩阵。可以通过以下方式实现:

k = 2
X = np.empty((0, k))
X = np.append(X, np.array([[69, 69]]), axis=0)
X = np.append(X, [[420, 420]], axis=0)
X = np.append(X, [[42069, 42069]], axis=0)
X = np.append(X, [[69420, 69420]], axis=0)

这将产生以下输出:

array([[   69,    69],
       [  420,   420],
       [42069, 42069],
       [69420, 69420]])
英文:

If i understood you right, you want an empty array that would grow at run time. Assuming the data you append is length k and you run in n times, you will get a n x k matrix. So this can be done by

k = 2
X = np.empty((0, k))
X = np.append(X, np.array([[69, 69]]),axis=0)
X = np.append(X,[[420,420]], axis=0)
X = np.append(X,[[42069,42069]], axis=0)
X = np.append(X,[[69420,69420]], axis=0)

This will give an an output of

array([[   69,    69],
       [  420,   420],
       [42069, 42069],
       [69420, 69420]])

huangapple
  • 本文由 发表于 2023年6月1日 16:06:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76379867.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定