展平NumPy数组列表?

Jer*_*ang 42 python arrays numpy list-comprehension

看来我的数据格式为NumPy数组列表(type() = np.ndarray):

[array([[ 0.00353654]]), array([[ 0.00353654]]), array([[ 0.00353654]]), 
array([[ 0.00353654]]), array([[ 0.00353654]]), array([[ 0.00353654]]), 
array([[ 0.00353654]]), array([[ 0.00353654]]), array([[ 0.00353654]]), 
array([[ 0.00353654]]), array([[ 0.00353654]]), array([[ 0.00353654]]),
array([[ 0.00353654]])]
Run Code Online (Sandbox Code Playgroud)

我想把它变成一个polyfit函数:

m1 = np.polyfit(x, y, deg=2)
Run Code Online (Sandbox Code Playgroud)

但是,它返回错误: TypeError: expected 1D vector for x

我假设我需要将我的数据展平为:

[0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654 ...]
Run Code Online (Sandbox Code Playgroud)

我已经尝试了列表理解,它通常适用于列表列表,但是这正如预期的那样无效:

[val for sublist in risks for val in sublist]
Run Code Online (Sandbox Code Playgroud)

最好的方法是什么?

Div*_*kar 42

您可以使用numpy.concatenate,顾名思义,基本上将这样一个输入列表的所有元素连接成一个NumPy数组,就像这样 -

import numpy as np
out = np.concatenate(input_list).ravel()
Run Code Online (Sandbox Code Playgroud)

如果您希望最终输出为列表,则可以扩展解决方案,如下所示 -

out = np.concatenate(input_list).ravel().tolist()
Run Code Online (Sandbox Code Playgroud)

样品运行 -

In [24]: input_list
Out[24]: 
[array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]]),
 array([[ 0.00353654]])]

In [25]: np.concatenate(input_list).ravel()
Out[25]: 
array([ 0.00353654,  0.00353654,  0.00353654,  0.00353654,  0.00353654,
        0.00353654,  0.00353654,  0.00353654,  0.00353654,  0.00353654,
        0.00353654,  0.00353654,  0.00353654])
Run Code Online (Sandbox Code Playgroud)

转换为列表 -

In [26]: np.concatenate(input_list).ravel().tolist()
Out[26]: 
[0.00353654,
 0.00353654,
 0.00353654,
 0.00353654,
 0.00353654,
 0.00353654,
 0.00353654,
 0.00353654,
 0.00353654,
 0.00353654,
 0.00353654,
 0.00353654,
 0.00353654]
Run Code Online (Sandbox Code Playgroud)

  • @Athena 请发布一个新问题。目前还不清楚数据格式到底是什么。 (2认同)

Tim*_*sen 6

itertools另一种用于展平数组的方法:

import itertools

# Recreating array from question
a = [np.array([[0.00353654]])] * 13

# Make an iterator to yield items of the flattened list and create a list from that iterator
flattened = list(itertools.chain.from_iterable(a))
Run Code Online (Sandbox Code Playgroud)

这个解决方案应该非常,请参阅/sf/answers/28579701/了解更多说明。

如果结果数据结构应该是numpy数组,请使用numpy.fromiter()将迭代器耗尽到数组中:

# Make an iterator to yield items of the flattened list and create a numpy array from that iterator
flattened_array = np.fromiter(itertools.chain.from_iterable(a), float)
Run Code Online (Sandbox Code Playgroud)

文档itertools.chain.from_iterable() https://docs.python.org/3/library/itertools.html#itertools.chain.from_iterable

文档numpy.fromiter() https://docs.scipy.org/doc/numpy/reference/ generated/numpy.fromiter.html


ayo*_*rgo 5

也可以通过

np.array(list_of_arrays).flatten().tolist()
Run Code Online (Sandbox Code Playgroud)

导致

[0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654]
Run Code Online (Sandbox Code Playgroud)

更新资料

正如@aydow在评论中指出的那样,numpy.ndarray.ravel如果不关心获取副本或视图,使用起来可能会更快

np.array(list_of_arrays).ravel()
Run Code Online (Sandbox Code Playgroud)

虽然,根据文档

当在尽可能多的情况下需要查看时,arr.reshape(-1)可能会更好。

换一种说法

np.array(list_of_arrays).reshape(-1)
Run Code Online (Sandbox Code Playgroud)

最初的建议我的是使用numpy.ndarray.flatten的是回报的副本,每次会影响性能。

现在,让我们看一下上面列出的解决方案的时间复杂度如何与使用perfplot软件包进行类似OP的设置进行比较

import perfplot

perfplot.show(
    setup=lambda n: np.random.rand(n, 2),
    kernels=[lambda a: a.ravel(),
             lambda a: a.flatten(),
             lambda a: a.reshape(-1)],
    labels=['ravel', 'flatten', 'reshape'],
    n_range=[2**k for k in range(16)],
    xlabel='N')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

这里flatten展示了分段线性复杂度,可以通过将初始数组的副本与的恒定复杂度进行比较ravelreshape返回视图来合理解释。

还值得注意的是,完全可以预见的是,转换输出.tolist()会使这三个输出的性能均匀地线性化。


kma*_*o23 5

另一种简单的方法是使用以下方法numpy.hstack()删除单例维度:squeeze()

In [61]: np.hstack(list_of_arrs).squeeze()
Out[61]: 
array([0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654,
       0.00353654, 0.00353654, 0.00353654, 0.00353654, 0.00353654,
       0.00353654, 0.00353654, 0.00353654])
Run Code Online (Sandbox Code Playgroud)