初始化多个Numpy数组(多个赋值)-如MATLAB deal()

2024-05-14 09:38:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我找不到任何描述如何做到这一点的东西,这导致我认为我没有以正确的惯用Python方式做到这一点。我们也希望您能提供一些关于“正确的”Python方法的建议。

我有一堆变量用于我正在编写的数据记录器(任意日志长度,已知最大长度)。在MATLAB中,我将它们初始化为长度为n的一维零数组,n大于我看到的条目数,在日志循环中分配每个单独的元素variable(measurement_no) = data_point,并在测量结束时修剪掉多余的零。初始化如下:

[dData gData cTotalEnergy cResFinal etc] = deal(zeros(n,1));

有没有办法在Python/NumPy中这样做,这样我就不必把每个变量放在自己的行上:

dData = np.zeros(n)
gData = np.zeros(n)
etc.

我也希望不只是做一个大矩阵,因为跟踪哪个列是哪个变量是不愉快的。或许解决方案是生成(length x numvars)矩阵,并将列切片分配给各个变量?

编辑:假设在结束时,我将拥有许多相同长度的向量;例如,我的后处理将获取每个日志文件,计算一组单独的度量(>;50),存储它们,然后重复,直到所有日志都被处理完。然后,我为我计算的所有不同度量生成直方图、means/maxes/sigmas/etc。既然在Python中初始化50+向量显然不容易,那么最好的(最干净的代码和良好的性能)方法是什么?


Tags: 数据方法度量np方式zerosetc矩阵
3条回答

没有什么不正常的

dData = np.zeros(n)
gData = np.zeros(n)
etc.

你可以把它们放在一条线上,但没有特别的理由。

dData, gData = np.zeros(n), np.zeros(n)

不要尝试dData = gData = np.zeros(n),因为对dData的更改会改变gData(它们指向同一个对象)。出于同样的原因,您通常不想使用x = y = []

MATLAB中的deal是一种方便,但并不神奇。以下是八度音阶是如何实现的

function [varargout] = deal (varargin)
  if (nargin == 0)
    print_usage ();
  elseif (nargin == 1 || nargin == nargout)
    varargout(1:nargout) = varargin;
  else
    error ("deal: nargin > 1 and nargin != nargout");
  endif

endfunction

与Python相反,在八度音阶(可能还有MATLAB)

one=two=three=zeros(1,3)

为3个变量分配不同的对象。

还请注意,MATLAB如何将deal作为分配单元格和结构数组内容的一种方式。http://www.mathworks.com/company/newsletters/articles/whats-the-big-deal.html

如果你真的想在一行代码中完成这项工作,你可以创建一个由零组成的(n_vars, ...)数组,然后沿着第一个维度展开它:

a, b, c = np.zeros((3, 5))
print(a is b)
# False

另一种选择是使用列表理解或生成器表达式:

a, b, c = [np.zeros(5) for _ in range(3)]   # list comprehension
d, e, f = (np.zeros(5) for _ in range(3))   # generator expression
print(a is b, d is e)
# False False

不过,要小心!您可能认为在包含对np.zeros()的调用的列表或元组上使用*运算符可以实现相同的功能,但它不能:

h, i, j = (np.zeros(5),) * 3
print(h is i)
# True

这是因为元组中的表达式首先被求值。np.zeros(5)因此只调用一次,重复元组中的每个元素最终都是对同一数组的引用。这也是为什么不能只使用a = b = c = np.zeros(5)的原因。

除非您真的需要分配大量的空数组变量,并且非常关心如何使代码紧凑(!),为了便于阅读,我建议在单独的行上初始化它们。

如果将数据放在collections.defaultdict中,则不需要执行任何显式初始化。所有内容将在第一次使用时初始化。

import numpy as np
import collections
n = 100
data = collections.defaultdict(lambda: np.zeros(n))
for i in range(1, n):
    data['g'][i] = data['d'][i - 1]
    # ...

相关问题 更多 >

    热门问题