用不同的方法填充缺失数据
Filling missing data with different methods
我有一组带有时间戳、值和质量标志的数据。一些时间戳缺少值和质量标志,需要用对周围数据的依赖来填充。即,
- 如果包含 NaN 数据的有效数据的质量标志不同,则将值和质量标志设置为与具有最高质量标志的括号行相同。在下面的示例中,第一组 NaN 将替换为 qf=3 和 value=3.
- 如果质量标志相同,则在任一侧的两个有效值之间插入值。在示例中,第二组 NaN 将替换为 qf = 1 and v = 6 and 9.
代码:
import datetime
import pandas as pd
start = datetime.strptime("2004-01-01 00:00","%Y-%m-%d %H:%M")
end = datetime.strptime("2004-01-01 03:00","%Y-%m-%d %H:%M")
df = pd.DataFrame(\
data = {'v' : [1,2,'NaN','NaN','NaN',3,2,1,5,3,'NaN','NaN',12,43,23,12,32,12,12],\
'qf': [1,1,'NaN','NaN','NaN',3,1,5,1,1,'NaN','NaN',1,3,4,2,1,1,1]},\
index = pd.date_range(start, end,freq="10min"))
我试图通过找到 NA 行并循环遍历它们来解决这个问题,以修复第一个标准,然后使用插值来解决第二个问题。但是,这真的很慢,因为我正在处理大量数据。
一种方法是进行所有可能的填充,然后在其中进行适当的选择。在必要时执行 df = df.astype(float)
之后(您的示例使用字符串 "NaN"
),像这样的东西应该可以工作:
is_null = df.qf.isnull()
fill_down = df.ffill()
fill_up = df.bfill()
df.loc[is_null & (fill_down.qf > fill_up.qf)] = fill_down
df.loc[is_null & (fill_down.qf < fill_up.qf)] = fill_up
df = df.interpolate()
它做的工作比必要的多,但很容易看出它在做什么,而且它所做的工作是矢量化的,因此发生得很快。在你的数据集扩展到约 1000 万行(具有相同的空值密度)的版本上,它在我的旧笔记本上需要约 6 秒。根据您的要求可能就足够了。
我有一组带有时间戳、值和质量标志的数据。一些时间戳缺少值和质量标志,需要用对周围数据的依赖来填充。即,
- 如果包含 NaN 数据的有效数据的质量标志不同,则将值和质量标志设置为与具有最高质量标志的括号行相同。在下面的示例中,第一组 NaN 将替换为 qf=3 和 value=3.
- 如果质量标志相同,则在任一侧的两个有效值之间插入值。在示例中,第二组 NaN 将替换为 qf = 1 and v = 6 and 9.
代码:
import datetime
import pandas as pd
start = datetime.strptime("2004-01-01 00:00","%Y-%m-%d %H:%M")
end = datetime.strptime("2004-01-01 03:00","%Y-%m-%d %H:%M")
df = pd.DataFrame(\
data = {'v' : [1,2,'NaN','NaN','NaN',3,2,1,5,3,'NaN','NaN',12,43,23,12,32,12,12],\
'qf': [1,1,'NaN','NaN','NaN',3,1,5,1,1,'NaN','NaN',1,3,4,2,1,1,1]},\
index = pd.date_range(start, end,freq="10min"))
我试图通过找到 NA 行并循环遍历它们来解决这个问题,以修复第一个标准,然后使用插值来解决第二个问题。但是,这真的很慢,因为我正在处理大量数据。
一种方法是进行所有可能的填充,然后在其中进行适当的选择。在必要时执行 df = df.astype(float)
之后(您的示例使用字符串 "NaN"
),像这样的东西应该可以工作:
is_null = df.qf.isnull()
fill_down = df.ffill()
fill_up = df.bfill()
df.loc[is_null & (fill_down.qf > fill_up.qf)] = fill_down
df.loc[is_null & (fill_down.qf < fill_up.qf)] = fill_up
df = df.interpolate()
它做的工作比必要的多,但很容易看出它在做什么,而且它所做的工作是矢量化的,因此发生得很快。在你的数据集扩展到约 1000 万行(具有相同的空值密度)的版本上,它在我的旧笔记本上需要约 6 秒。根据您的要求可能就足够了。