展平列表和标量列表

Ash*_*hum 1 python arrays numpy list multidimensional-array

所以对于矩阵,我们有像numpy.flatten()这样的方法

np.array([[1,2,3],[4,5,6],[7,8,9]]).flatten()
Run Code Online (Sandbox Code Playgroud)

[1,2,3,4,5,6,7,8,9]

如果我想从获得np.array([[1,2,3],[4,5,6],7])[1,2,3,4,5,6,7]
是否存在执行类似功能的现有功能?

hpa*_*ulj 6

对于不均匀的列表,数组是一个对象dtype,(和1d,所以flatten不会改变它)

In [96]: arr=np.array([[1,2,3],[4,5,6],7])
In [97]: arr
Out[97]: array([[1, 2, 3], [4, 5, 6], 7], dtype=object)
In [98]: arr.sum()
...
TypeError: can only concatenate list (not "int") to list
Run Code Online (Sandbox Code Playgroud)

7元素是给问题.如果我将其更改为列表:

In [99]: arr=np.array([[1,2,3],[4,5,6],[7]])
In [100]: arr.sum()
Out[100]: [1, 2, 3, 4, 5, 6, 7]
Run Code Online (Sandbox Code Playgroud)

我在这里使用一个技巧.数组列表的元素和列表[1,2,3]+[4,5]是连接的.

基本点是对象数组不是2d数组.从许多方面来说,它更像是列表清单.

最好的列表flattener是 chain

In [104]: list(itertools.chain(*arr))
Out[104]: [1, 2, 3, 4, 5, 6, 7]
Run Code Online (Sandbox Code Playgroud)

虽然它也会扼杀整数7版本.

连接和hstack

如果数组是列表列表(不是列表和标量的原始混合)那么np.concatenate可行.它迭代对象,就像它是一个列表一样.

混合原始列表concatenate不起作用,但hstack确实如此

In [178]: arr=np.array([[1,2,3],[4,5,6],7])
In [179]: np.concatenate(arr)
...
ValueError: all the input arrays must have same number of dimensions
In [180]: np.hstack(arr)
Out[180]: array([1, 2, 3, 4, 5, 6, 7])
Run Code Online (Sandbox Code Playgroud)

那是因为hstack首先迭代列表并确保所有元素都是atleast_1d.这种额外的迭代使其更加稳健,但代价是处理速度.

时间测试

In [170]: big1=arr.repeat(1000)
In [171]: timeit big1.sum()
10 loops, best of 3: 31.6 ms per loop
In [172]: timeit list(itertools.chain(*big1))
1000 loops, best of 3: 433 µs per loop
In [173]: timeit np.concatenate(big1)
100 loops, best of 3: 5.05 ms per loop
Run Code Online (Sandbox Code Playgroud)

大小加倍

In [174]: big1=arr.repeat(2000)
In [175]: timeit big1.sum()
10 loops, best of 3: 128 ms per loop
In [176]: timeit list(itertools.chain(*big1))
1000 loops, best of 3: 803 µs per loop
In [177]: timeit np.concatenate(big1)
100 loops, best of 3: 9.93 ms per loop
In [182]: timeit np.hstack(big1)    # the extra iteration hurts hstack speed
10 loops, best of 3: 43.1 ms per loop
Run Code Online (Sandbox Code Playgroud)

sum的大小是二次的

res=[]
for e in bigarr: 
   res += e
Run Code Online (Sandbox Code Playgroud)

res 随着e的数量增长,所以每个迭代步骤都更昂贵.

chain 时代最好的.

  • 这看起来像直接黑客.这个`sum`被定义为在'numpy`中以这种方式工作吗? (2认同)
  • 注意 - 如果子列表确实具有相同的长度,则`array`调用将产生一个真正的2D数组,并且`sum`调用将产生一个整数和而不是连接列表.(此外,这是一种二次方式进行连接的方法,即使它有效.) (2认同)