【发布时间】:2021-07-20 20:36:29
【问题描述】:
我有一些跨越大约 8 个月的房价数据,并跟踪房价从房屋上市到售出的过程。我想填补中间数据中的几个空白,但我想将 NaN 保留在每个空白的末尾。
举个简单的例子,假设我们有房子 1,它在“第 4 天”以 200000 的价格上市,在“第 9 天”以 190000 的价格出售。我们有 house2 在第 1 天到第 12 天保持在 180000 并且在那个时间窗口内不出售。但是,第 6 天和第 7 天出了点问题,我丢失了数据:
house1 = [NaN, NaN, NaN, 200000, 200000, NaN, NaN, 200000, 190000, NaN, NaN, NaN]
house2 = [180000, 180000, 180000, 180000, 180000, NaN, NaN, 180000, 180000, 180000, 180000, 180000]
现在想象一下,这些是 Pandas Dataframes 中按日期索引的列,而不是常规数组。
问题是,我通常用来填补这里空白的函数是DataFrame.fillna(),使用 backfill 或 ffill 方法。如果我使用 ffill,house1 会返回:
house1 = [NaN, NaN, NaN, 200000, 200000, 200000, 200000, 200000, 190000, 190000, 190000, 190000]
这填补了空白,但也错误地填写了销售日之后的数据。如果我改用回填,我会得到:
house1 = [200000, 200000, 200000, 200000, 200000, 200000, 200000, 200000, 190000, NaN, NaN, NaN]
再次填补了空白,但这次也填补了数据的前端。如果我将 'limit=2' 与 ffill 一起使用,那么我得到的是:
house1 = [NaN, NaN, NaN, 200000, 200000, 200000, 200000, 200000, 190000, 190000, 190000, NaN]
它再次填补了空白,但随后它也开始填补“真实”数据结束位置之外的数据。
到目前为止,我的解决方案是编写以下函数:
def fillGaps(houseDF):
"""Fills up holes in the housing data"""
def fillColumns(column):
filled_col = column
lastValue = None
# Keeps track of if we are dealing with a gap in numbers
gap = False
i = 0
for currentValue in filled_col:
# Loops over all the nans before the numbers begin
if not isANumber(currentValue) and lastValue is None:
pass
# Keeps track of the last number we encountered before a gap
elif isANumber(currentValue) and (gap is False):
lastIndex = i
lastValue = currentValue
# Notes when we encounter a gap in numbers
elif not isANumber(currentValue):
gap = True
# Fills in the gap
elif isANumber(currentValue):
gapIndicies = range(lastIndex + 1, i)
for j in gapIndicies:
filled_col[j] = lastValue
gap = False
i += 1
return filled_col
filled_df = houseDF.apply(fillColumns, axis=0)
return filled_df
它只是跳过前面的所有 NaN,填充间隙(由实际值之间的 NaN 组定义),最后不填充 NaN。
有没有更简洁的方法,或者我不知道的内置 pandas 函数?
【问题讨论】: