【问题标题】:filling data gaps with monthly averages (Python) [closed]用每月平均值填补数据空白(Python)[关闭]
【发布时间】:2014-01-26 11:32:25
【问题描述】:

我有一个超过 10 年的很长的时间序列,每半小时测量一次,作为 Csv 文件。测量设备时常发生故障。我想用月平均值或移动平均值(忽略缺失值)来插入这个差距。我想我需要一个 for 循环来做到这一点,但我不知道如何准确地做到这一点。有人可以帮助我吗? 我的数据如下所示:

10-Oct-2010 21:15   0.00271
10-Oct-2010 21:45   0.00408
10-Oct-2010 22:15   -0.00228
10-Oct-2010 22:45   0.00433
10-Oct-2010 23:15   0.00421
10-Oct-2010 23:45   0.00224
11-Oct-2010 00:15   -0.01678
11-Oct-2010 00:45   -0.00059
11-Oct-2010 01:15   -0.00371
11-Oct-2010 01:45   0.01353
11-Oct-2010 02:15   0.00108
11-Oct-2010 02:45   0.00101
11-Oct-2010 03:15   -0.00159
11-Oct-2010 03:45   0.0011

我当前的代码是:

import pandas as pd
ts = pd.read_csv('C:\Python27\Scripts\ET_T_2000.csv', sep=';', parse_dates=[['date', 'time']])
ts1 = ts.set_index('date_time')['ET'].resample('D', how='sum')
ts1.to_csv('sum.csv')

所以我得到了蒸发数据的每日总和。我也可以重新采样每月的每日平均值,但我不知道如何告诉 Python 它需要为每个间隔使用该特定月份的平均值。

【问题讨论】:

  • 我建议从两个周围的值中插入缺失值;这应该比每月平均值更接近真实的缺失值。

标签: python for-loop pandas average interpolation


【解决方案1】:

不要随便更改源数据:始终保持原始数据不变。

然后,数据的任何消费者都可以决定与数据显示的内容以及他们打算如何处理数据相关的特定插值方案。

特别是,如果您正在对数据进行一些波动性分析,那么您输入的插值将具有人为地减少该波动性的效果。

PS你说你有一个字符分隔值文件,但是分隔符是什么?)

【讨论】:

  • 分隔符是“;”。我需要对其进行插值,因为我想总结每年的所有值以创建水平衡。该值是蒸发数据。如果我建立一个包含这么多缺失值的一年的累积总和,那么总和将远低于实际蒸发量。所以我需要插值。
  • (我在文件中看不到任何分隔符)。在这种情况下,请考虑计算总和 (s) 和记录次数 (t),然后使用 s * p / t 将其扩展到全年,其中 p 是潜在的记录数。
  • 也许您应该对现有值求和,对它们进行计数,然后使用它们的平均值来估计一整年的总和。如果数据丢失与极值相关(例如,如果传感器总是在水位极高时中断),则此处插值可能会严重伪造值,因为这样插值会将极值延长到比实际更长的时间段。跨度>
【解决方案2】:

由于缺失值的差距如此之大,我想您最好还是将它们保留为 NAN,并调整您的计算,以便它们可以处理缺失的数据。看起来你正在用它进行财务模拟,从长远来看,如果你修改实际的原始数据,它总是会适得其反。如果您使用 Numpy 进行计算,Bottleneck 添加了一堆修改过的函数,这些函数会跳过数组中的 NAN 值,例如计算均值时等等。最好继续这样做!

【讨论】:

    【解决方案3】:

    注意:这应该是评论,但我没有代表 :)

    Pandas 在系列和数据帧上都有一个很好的“插值”功能:(http://pandas.pydata.org/pandas-docs/dev/missing_data.html#interpolation)。我将建议,特别是如果您有“几天”的缺失数据,您只需将值保留为 NaN (http://pandas.pydata.org/pandas-docs/dev/missing_data.html#working-with-missing-data)。 Pandas 对具有 NA 值的绘图提供了非常好的支持,并且看到具有正确测量值的绘图,然后很容易解释“间隙”。该方法还提供了额外的信息,假设您正在查看图表并且您发现周末比其他日子有更多的差距,这可能表明测量设备在周末(或其他)不太稳定。

    【讨论】:

    • 好的,谢谢。我知道熊猫的这个插值函数,但它只使用了间隙前后的一些值。这太不准确了。数据代表森林中的蒸发。如果某天设备发生故障并且只插入间隙前后的值,那么我一天都没有得到课程,而且通常不准确。
    • 我同意,对于您的用例,插值可能不是您想要的,这就是为什么我建议将数据保留为 NA 值。 Pandas 对它有很好的支持,像 'mean,min,max,std' 这样的函数在 NA 值下都可以正常工作(做正确的事情)。如果您将缺失值替换为“月平均值”,那么所有这些统计数据都将不正确。
    【解决方案4】:

    如果你的值在一个元组列表中(唉,你没有说明你的数据结构)(timestamp, value)

    data = [ (1, 3.), (2, 5.), (3, 0.), (6, 3.), (7, 3.), (9, 2.), (10, 0.) ]
    timestampDistance = 1
    
    def interpolateGap(ts0, v0, ts1, v1):
      count = (ts1 - ts0) / timestampDistance
      return [ (ts0 + i * timestampDistance, v0 + (v1 - v0) * i / count)
        for i in range(1, count) ]
    
    def fillGap(data, pos, ts0, v0, ts1, v1):
      data[pos+1:pos] = interpolateGap(ts0, v0, ts1, v1)
    
    for i in range(len(data)-1, 1, -1):
      timestamp, value = data[i]
      previousTimestamp, previousValue = data[i-1]
      if previousTimestamp + timestampDistance < timestamp:
        fillGap(data, i-1, previousTimestamp, previousValue, timestamp, value)
    
    print data
    

    这将打印出来

    [(1, 3.0), (2, 5.0), (3, 0.0), (4, 1.0), (5, 2.0), (6, 3.0), (7, 3.0), (8, 2.5), (9, 2.0), (10, 0.0)]
    

    【讨论】:

    • 好吧,我有一个包含 160,000 个条目的 csv 文件。缺失值有时是几天(这意味着一天 = 丢失 48 个测量值),有时是几周。我认为这个解决方案只适用于一个短系列,不是吗?
    • 我看不出为什么即使一百万个条目也会造成问题。但当然,插值不会模拟典型的每日曲线。您只会得到一条从现有点到下一个点的直线。
    • 好的,感谢您的努力!据我了解,它从最后一个已知值和差距后的下一个值建立平均值,对吗?我有两个问题:1)是否可以用月平均(或 30 天移动平均)来填补空白,因为这样会更准确? 2)我的数据最初在一个 csv 文件中,我需要导入到 python。如果我使用“data = pd.read_csv('ET_T_2000.csv', sep=';', parse_dates=[['date', 'time']]) 我收到错误“KeyError: u'no item named 187055' ".csv 文件有 187057 行。你知道如何修复它吗?
    • 当然,您可以计算每月平均值并用它来填补任何空白,但这更复杂(而且这不是一个用于开发解决方案的网站,而只是用于回答问题)。关于 KeyError:听起来像是你应该在这里问的另一个问题(不要将所有问题混为一个问题 ;-)
    猜你喜欢
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 2015-06-28
    • 1970-01-01
    相关资源
    最近更新 更多