返回正确维数数组的python方法

2024-10-01 04:51:16 发布

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

我想创建一个函数,如果给定了一个numpy数组,则返回一个多维numpy数组。例如:

import numpy as np;
def running_average(data,windowSize):
    dShape = np.shape(data);
    if(len(dShape)==1):
        raOut = np.zeros(len(data));
        rSum = 0.0;
        for row,value in enumerate(data):
            if row<windowSize:
                rSum+=float(value);
            else:
                rSum=rSum-data[row-windowSize]+value;
            raOut[row]=rSum/windowSize;
    else:
        raOut = np.zeros(dShape);
        for col in xrange(dShape[1]):
            rSum=0.0;
            for row,value in enumerate(data[:,col]):
                if row<windowSize:
                    rSum+=float(value);
                else:
                    rSum=rSum-data[row-windowSize,col]+value;
                raOut[row,col]=rSum/windowSize;

    return raOut;

但是必须有一个很好的测试,这样我就不必在if和else语句中重复我自己。在

我对python比较新,preferred方法是什么?在


Tags: innumpyfordataifvaluenpcol
3条回答

我喜欢Peter的回答,但是这里有一个替代方法,对代码的更改更少。只需测试列数-如果没有列,就认为是'1'。在

import numpy as np
def running_average(data,windowSize):
    dShape = np.shape(data)

    try:
        dShape[1]
    except:
        data = [data]
        dShape = np.shape(data)

    raOut = np.zeros(dShape)
    for col in dShape[1]:
        rSum=0.0
        for row,value in enumerate(data[:][col]):
            if row<windowSize:
                rSum+=float(value)
            else:
                rSum=rSum-data[row-windowSize][col]+value
            raOut[row][col]=rSum/windowSize

    return np.squeeze(raOut)

首先,你考虑的太多了。np.zeros(dShape)将执行您想要的操作,无论{}是一维数组还是二维数组。(在一维数组的情况下,dShape将是一个单元素元组,zeros知道如何处理它。)

第二,停止在if语句的行尾和括号中使用分号。这是Python,你不需要它们。在

至于重复代码,我会将for row, value in ...循环中的所有内容抽象为迭代器。在

所以:

import numpy as np

def average_iterator(data, windowSize):
  rSum = 0.0
  for row, value in enumerate(data):
    if row < windowSize:
      rSum += float(value)
    else:
      rSum = rSum - data[row-windowSize] + value
    yield row, rSum / windowSize

def running_average(data, windowSize):
  dShape = np.shape(data)
  raOut = np.zeros(dShape)
  if len(dShape) == 1:
    for row, avg in average_iterator(data, windowSize):
      raOut[row] = avg
  else:
    for col in xrange(dShape[1]):
      for row, avg in average_iterator(data[:,col], windowSize):
        raOut[row, col] = avg
  return raOut

您还可以在running_average内使average_iterator成为本地定义,在这种情况下,您不必传入windowSize。在

比如说:

def running_avg(data, ws):
    tmp = np.cumsum(data, axis=-1, dtype='float')
    ra = (tmp[..., ws:] - tmp[..., :-ws]) / ws
    return ra

这将取最后一个轴上的平均值,如果你想变得更聪明,你可以让函数取一个轴参数,然后取任意轴上的平均值。在

更新

我相信这个版本和你上面的代码是一致的。在

^{pr2}$

对于更一般的问题,使用numpy内置函数(如cumsum)会有所帮助,因为它们已经这样做了,但是如果必须循环,可以使用A=np.零(A.shape)获取与输入相同形状的数组,然后使用[…,i]始终对最后一个维度进行操作,或者使用[…,i,:]始终对倒数第二个维度进行操作,依此类推。有时人们也会做数据=np.滚动(data,axis)将轴移动到开始位置,然后使用[i]对第一个维度进行操作,如果需要,将轴向后移动。在

更新2:

我刚想起来为什么以下是一个非常坏的主意(至少在这种情况下):

ra[..., ws:] -= ra[..., :-ws]

您应该改用这个:

ra[..., ws:] = ra[..., ws:] - ra[..., :-ws]

相关问题 更多 >