Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 仅使用熊猫填充间隙,而不使用末端的NaN_Python_Numpy_Pandas - Fatal编程技术网

Python 仅使用熊猫填充间隙,而不使用末端的NaN

Python 仅使用熊猫填充间隙,而不使用末端的NaN,python,numpy,pandas,Python,Numpy,Pandas,我有一些大约8个月的房价数据,随着房屋上市直到出售,我会跟踪房价。中间的数据有几个空缺,我想填入,但我想把NANS留在每个未被触碰的结尾。 举个简单的例子,假设我们有house1,它在“第4天”以200000的价格上市,在“第9天”以190000的价格出售。我们的House 2在第1-12天的价格为180000,在这个时间窗口内不销售。但是,第6天和第7天出了问题,我丢失了数据: house1 = [NaN, NaN, NaN, 200000, 200000, NaN, NaN, 200000,

我有一些大约8个月的房价数据,随着房屋上市直到出售,我会跟踪房价。中间的数据有几个空缺,我想填入,但我想把NANS留在每个未被触碰的结尾。 举个简单的例子,假设我们有house1,它在“第4天”以200000的价格上市,在“第9天”以190000的价格出售。我们的House 2在第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]
现在想象一下,这些列不是常规数组,而是数据帧中按日期索引的列

问题是,我通常用来填补空白的函数将使用回填或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]
同样,它填补了空白,但这次它也填补了数据的前端。如果我对ffill使用'limit=2',那么我得到的是:

house1 = [NaN, NaN, NaN, 200000, 200000, 200000, 200000, 200000, 190000, 190000, 190000, NaN]
再一次,它填补了空白,但随后它也开始填补超出“真实”数据结尾的数据

到目前为止,我的解决方案是编写以下函数:

它只是跳过前面的所有NaN,填补空白(由实际值之间的NaN组定义),而不在最后填补NaN


有没有更干净的方法来实现这一点,或者有我不知道的内置pandas函数?

您可以在本系列的某些部分使用
fillna
。根据您的描述,
fillna
只应在第一个非NaN之后、最后一个非NaN之前填充NaN:

import numpy as np
import pandas as pd


def fill_column(house):
    house = house.copy()
    non_nans = house[~house.apply(np.isnan)]
    start, end = non_nans.index[0], non_nans.index[-1]
    house.ix[start:end] = house.ix[start:end].fillna(method='ffill')
    return house


house1 = pd.Series([np.nan, np.nan, np.nan, 200000, 200000, np.nan, np.nan, 200000, 190000, np.nan, np.nan, np.nan])
print fill_column(house1)
输出:

0        NaN
1        NaN
2        NaN
3     200000
4     200000
5     200000
6     200000
7     200000
8     190000
9        NaN
10       NaN
11       NaN

请注意,这假设该系列至少包含两个非NaN,对应于第一天和最后一天的价格。

我在一年后找到了这个答案,但需要它来处理多列数据帧,因此我想将我的解决方案留在这里,以防其他人需要相同的解决方案。我的函数只是YS-L的一个修改版本

def fillna_downbet(df):
    df = df.copy()
    for col in df:
        non_nans = df[col][~df[col].apply(np.isnan)]
        start, end = non_nans.index[0], non_nans.index[-1]
        df[col].loc[start:end] = df[col].loc[start:end].fillna(method='ffill')
    return df

谢谢

另一个解决方案是使用多列数据帧

df.fillna(method='ffill') + (df.fillna(method='bfill') * 0)
它是如何工作的

第一个
fillna
向前填充值。这几乎就是我们想要的,只是它在每个系列的末尾都会留下一条填充值的轨迹

第二个
fillna
向后填充我们乘以零的值。结果是我们不需要的尾随值将为NaN,其他所有值都将为0


最后,利用x+0=x和x+NaN=NaN这一事实,我们将两者相加。

这是一个出色的解决方案。非常感谢。
df.fillna(method='ffill') + (df.fillna(method='bfill') * 0)