【问题标题】:Finding an average but ignoring any zero in a list [Python]查找平均值但忽略列表中的任何零 [Python]
【发布时间】:2015-01-01 18:28:35
【问题描述】:

我有一个温度数据的文本文件,如下所示:

3438012868.0    0.0 21.7    22.6    22.5    22.5    21.2
3438012875.0    0.0 21.6    22.6    22.5    22.5    21.2
3438012881.9    0.0 21.7    22.5    22.5    22.5    21.2
3438012888.9    0.0 21.6    22.6    22.5    22.5    21.2
3438012895.8    0.0 21.6    22.5    22.6    22.5    21.3
3438012902.8    0.0 21.6    22.5    22.5    22.5    21.2
3438012909.7    0.0 21.6    22.5    22.5    22.5    21.2
3438012916.6    0.0 21.6    22.5    22.5    22.5    21.2
3438012923.6    0.0 21.6    22.6    22.5    22.5    21.2
3438012930.5    0.0 21.6    22.5    22.5    22.5    21.2
3438012937.5    0.0 21.7    22.5    22.5    22.5    21.2
3438012944.5    0.0 21.6    22.5    22.5    22.5    21.3
3438012951.4    0.0 21.6    22.5    22.5    22.5    21.2
3438012958.4    0.0 21.6    22.5    22.5    22.5    21.3
3438012965.3    0.0 21.6    22.6    22.5    22.5    21.2
3438012972.3    0.0 21.6    22.5    22.5    22.5    21.3
3438012979.2    0.0 21.6    22.6    22.5    22.5    21.2
3438012986.1    0.0 21.6    22.5    22.5    22.5    21.3
3438012993.1    0.0 21.6    22.5    22.6    22.5    21.2
3438013000.0    0.0 21.6    0.0     22.5    22.5    21.3
3438013006.9    0.0 21.6    22.6    22.5    22.5    21.2
3438013014.4    0.0 21.6    22.5    22.5    22.5    21.3
3438013021.9    0.0 21.6    22.5    22.5    22.5    21.3
3438013029.9    0.0 21.6    22.5    22.5    22.5    21.2
3438013036.9    0.0 21.6    22.6    22.5    22.5    21.2
3438013044.6    0.0 21.6    22.5    22.5    22.5    21.2

但整个文件要长得多,这是前几行。第一列是时间戳,接下来的 6 列是温度记录。我需要编写一个循环来找到 6 次测量的平均值,但会忽略 0.0 的测量,因为这只是意味着传感器没有打开。在测量的后期,第一列确实有一个测量值。有没有办法让我写一个 if 语句或另一种方法来只找到列表中非零数字的平均值?现在,我有:

time = []
t1 = []
t2 = []
t3 = []
t4 = []
t5 = []
t6 = []
newdate = []

temps = open('file_path','r')
sepfile = temps.read().replace('\n','').split('\r')
temps.close()

for plotpair in sepfile:
    data = plotpair.split('\t')
    time.append(float(data[0]))
    t1.append(float(data[1]))
    t2.append(float(data[2]))
    t3.append(float(data[3]))
    t4.append(float(data[4]))
    t5.append(float(data[5]))
    t6.append(float(data[6]))

for data_seconds in time:
    date = datetime(1904,1,1,5,26,02)
    delta = timedelta(seconds=data_seconds)
    newdate.append(date+delta)

for datapoint in t2,t3,t4,t5,t6:
    temperatures = np.array([t2,t3,t4,t5,t6]).mean(0).tolist()

仅查找最近 5 次测量的平均值。我希望找到一种更好的方法,它会忽略 0.0 并在第一列为非 0 时包含它。

【问题讨论】:

  • 您可以使用内置模块或第 3 方模块吗?
  • 你用的是python2还是python3?
  • 为什么要忽略,零,任何数字加零让它保持不变
  • @Hackaholic:1,2,3的平均值是2;而 1,2,3,0 的平均值是 1.5。看到问题了吗?
  • ohhh OP 希望在其中包含总计数

标签: python data-analysis


【解决方案1】:

之前的问题显示您已安装 NumPy。因此,使用 NumPy,您可以将零设置为 NaN,然后​​调用 np.nanmean 取平均值,忽略 NaN:

import numpy as np

data = np.genfromtxt('data')
data[data == 0] = np.nan
means = np.nanmean(data[:, 1:], axis=1)

产量

array([ 22.1  ,  22.08 ,  22.08 ,  22.08 ,  22.1  ,  22.06 ,  22.06 ,
        22.06 ,  22.08 ,  22.06 ,  22.08 ,  22.08 ,  22.06 ,  22.08 ,
        22.08 ,  22.08 ,  22.08 ,  22.08 ,  22.08 ,  21.975,  22.08 ,
        22.08 ,  22.08 ,  22.06 ,  22.08 ,  22.06 ])

【讨论】:

  • Prior questions show you have NumPy installed
  • 由于传感器已关闭,因此通常将 0 替换为 nan 也是有意义的。
  • 也许我不明白问题的上下文,但我似乎无法弄清楚为什么你在 data[:, 1:] 中使用 1,而不是 data[:, :] .对我来说,这只是导致失去了第一个平均值。
  • dtype 应该是 floatcomplexobject。否则, np.nan 替换会引发错误。 ValueError: cannot convert float NaN to integer
【解决方案2】:

您可以使用scipy.stats.tmean 制作截断/修剪的平均值

或者你可以检查float(data[X])是否等于0,然后再添加到对应的列表中

【讨论】:

    【解决方案3】:

    这将适用于 python3

    import csv
    
    with open('path/to/input') as infile, open('path/to/output', 'w') as outfile:
        outfile = csv.writer(outfile, delimiter='\t')
        for time, *temps in csv.reader(infile, delimiter='\t'):
            temps = [float(t) for t in temps if t!='0.0']
            avg = sum(temps)/len(temps)
            outfile.writerow([time, avg])
    

    【讨论】:

      【解决方案4】:
      with open('infile') as f1, with open('outfile','w') as f2:
          for x in f1:
              nums = [float(i) for i in x.strip().split() if i!='0.0']
              avg = sum(nums[1:])/len(nums[1:])
              f2.write("{}\t{}".format(nums[0],avg))
      

      【讨论】:

        猜你喜欢
        • 2019-03-30
        • 2015-03-05
        • 1970-01-01
        • 1970-01-01
        • 2020-12-10
        • 2015-05-17
        • 1970-01-01
        • 1970-01-01
        • 2012-02-20
        相关资源
        最近更新 更多