Dataframe 如何批量填充间隔空行
2019-07-15 本文已影响0人
Sdoopy
在开发过程中,碰到一个场景。在如下图1的Dataframe里,根据上一个有值行的值,填充下面的空。填充成如图2的样子。


写了一个小函数
def fill_up(df, interval):
"""
根据上一个有值行的值,批量填充间隔空行
:param df: Dataframe
:param interval: 有值行的间隔
"""
_df = df.copy()
tmp = _df[_df['A'].notnull()]
for index, row in tmp.iterrows():
row_piece = row[['A']]
fill = [row_piece for _ in range(interval - 1)]
_df.loc[index + 1: index + interval - 1, ['A']] = fill
return _df
其实interval也可以不需要,那就需要函数里计算间隔了,也简单,就不多写了。
可能会有人奇怪,为什么我会写row[['A']]而不是row['A'],这是因为实际中我是要批量修改多列,对于单列,row['A']当然是可以的,相当于取值,对于多列,如row[['A', 'B']],必须要这么写,才能取出两列的值。
PS: 在解决这个问题的过程中,我尝试了很多种方法。有一种方法虽然失败了,但是可以拿出来给大家借鉴一下。就是使用apply。
def fill_up(df, interval):
"""
根据上一个有值行的值,批量填充间隔空行
:param df: Dataframe
:param interval: 有值行的间隔
"""
_df = df.copy()
def apply_func(x):
return x[1] if x[1] != 0 else x[0]
_df = _df.fillna(0)
_df['A'] = _df['A'].rolling(2).apply(apply_func)
return _df
我本来想的是apply让每一行的值去依赖上一行,如果这一行有值,就保留原值,如果这一行没值,就用上一行的值去填充。结果发现填充好的结果会变成图3的样子。

结果说明apply的调用其实是针对原列,并不是时时刻刻改变的列。写在这里供大家参考。虽然多做几次循环也能实现,但是效率太低了。除非你的间隔正好是2,那用这个写法是最简洁的
发现了自己的愚蠢哈哈哈哈哈,原来Dataframe有一个填充方法,fillna, 里面的ffill方式就能直接做到。哎,之前找了很久都没找到这个方法,实在是太方便了