前言
在数据处理时,由于采集数据量有限,或者采集数据粒度过小,经常需要对数据重采样。在本例中,我们将实现一个类型超分辨率的操作。
思路:
- 首先将原始数据长度扩展为 3 倍,可以使用 loc[] 方法对索引扩展来生成,同时去掉尾部多余的数据。
- 再将每行数据扩展出的数据挖去(设置为空),这个操作我们在案例 使用 explode() 后不复制其他列 中有过讲解。
- 最后使用 DataFrame 的 interpolate() 插补方法会默认按线性逻辑进行填充。
使用步骤
读入数据
代码如下(示例):
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': [10, 20, 50, 40, 80,],
'B': [2, 8, 10, 6, 4, ],
})
df
# 这个数据共有 5 行,现在我们需要扩展它,在前相邻两个数据之间由一个扩展为 3 个。如 0 和 1 之间再增加两个数据,最终数据为 13 行。
# 新增加的数据行,按整体按线性插补的算法补充。
# 将索引重复三次:
df.index.repeat(3)
# 将得到的索引传入 loc[] 得到扩展数据:
df.loc[df.index.repeat(3)]
# 去掉尾部多余的数据:
(
df.loc[df.index.repeat(3)]
.iloc[:-3+1] # 删除最后三个(可为变量),再保留1个,方便以后封装
)
# 再接我们之前案例的方法将扩展出来的数据设置为空:
def func(d: pd.DataFrame):
d.iloc[1:, :] = None
return d
(
df.loc[df.index.repeat(3)]
.iloc[:-3+1]
.groupby(level=0)
.apply(func)
)
# 最后再用 interpolate() 插补数据,整体代码如下:
def func(d: pd.DataFrame):
d.iloc[1:, :] = None
return d # 将第一行及其之后的行设置为None
(
df.loc[df.index.repeat(3)] # 将df的每个索引值重复3次
.iloc[:-3+1] # 取除了最后3行的所有行
.groupby(level=0) # 按照索引值进行分组
.apply(func) # 对每个分组应用函数func
.interpolate() # 对缺失值进行插补
)
# 其他方法:
# 我们还可以尝试用分组方法合并进去空 DataFrame,然后再做插补。
none_df = pd.DataFrame([[None]*len(df.columns)], # 将空DataFrame与原DataFrame合并
columns=df.columns,
dtype=float,
)
none_df
(
df.groupby(level=0, group_keys=False) # 按照索引值进行分组
.apply(lambda x: pd.concat([x, *[none_df]*2])) # 将空DataFrame与原DataFrame合并
.interpolate() # 对缺失值进行插补
.iloc[:-2] # 取除了最后2行的所有行
)
总结
以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。