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)
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
也可以通过
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展示了分段线性复杂度,可以通过将初始数组的副本与的恒定复杂度进行比较ravel并reshape返回视图来合理解释。
还值得注意的是,完全可以预见的是,转换输出.tolist()会使这三个输出的性能均匀地线性化。
另一种简单的方法是使用以下方法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)
| 归档时间: |
|
| 查看次数: |
31577 次 |
| 最近记录: |