python - 前向填充上述值 pandas 的 block

标签 python pandas dataframe numpy ffill

我对在 pandas 的列中向前填充单个值和多个值很感兴趣。使用以下数据框:

import pandas as pd
df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
df
    0   1   2
0   1   2   3
1   4 NaN NaN
2 NaN NaN   9 

正向填充将产生:

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
df.fillna(method='ffill')
df
   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

但是,我需要一个类似 ffill 的方法来执行此操作,或者如果上面的值一个接一个地复制上面的所有值:

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, 5, 9], [None,None,None])
df
    0   1   2
0   1   2   3
1   4 NaN NaN
2 NaN   5   9 
3 NaN NaN NaN

导致:

df
    0   1   2
0   1   2   3
1   4   2   3
2   1   5   9 
3   4   5   9

主要编辑:在我的数据中,值将始终跟在值长度的未知倍数中的 NaN 之后。以 df[0] 为例,只要有 NaN,1,4 就会重复。唯一的规则是它们将是值 (2) 长度的倍数

最佳答案

您可以为缺失值和非缺失值创建连续值,然后为每列创建计数器并向前填充每组缺失值:

df = pd.DataFrame([[1, 2, 3], [4, None, 8], [None, 5, 9], [None,None,10],
                   [0, 2, None], [5, None, None], [None, 5, None], [None,None,None]])


print (df)
     0    1     2
0  1.0  2.0   3.0
1  4.0  NaN   8.0
2  NaN  5.0   9.0
3  NaN  NaN  10.0
4  0.0  2.0   NaN
5  5.0  NaN   NaN
6  NaN  5.0   NaN
7  NaN  NaN   NaN

m = df.isna()
g = m.ne(m.shift()).cumsum()
for c in df.columns:
    df[c] = df.groupby(g.groupby(c).cumcount())[c].ffill()

print (df)
     0    1     2
0  1.0  2.0   3.0
1  4.0  2.0   8.0
2  1.0  5.0   9.0
3  4.0  5.0  10.0
4  0.0  2.0   3.0
5  5.0  2.0   8.0
6  0.0  5.0   9.0
7  5.0  5.0  10.0

编辑:新解决方案通过第一个非缺失值创建的每组 newxt 缺失值重复非缺失值,此处使用 numpy.tile用于生成序列:

df = pd.DataFrame([[1, 2, 3], [4, None, 8], [None, 5, 9], [7,None,10],
                   [0, 2, None], [5, None, None], [None, 6, None], [None,8,None]
                   , [None,None,None], [None,None,None]])
print (df)
     0    1     2
0  1.0  2.0   3.0
1  4.0  NaN   8.0
2  NaN  5.0   9.0
3  7.0  NaN  10.0
4  0.0  2.0   NaN
5  5.0  NaN   NaN
6  NaN  6.0   NaN
7  NaN  8.0   NaN
8  NaN  NaN   NaN
9  NaN  NaN   NaN

g = (df.notna() & df.shift().isna()).cumsum()

def f(x):
    non_miss = x.dropna()
    return np.tile(non_miss, int(len(x) // len(non_miss) + 2))[:len(x)]

df = df.apply(lambda x: x.groupby(g[x.name]).transform(f))
print (df)
     0    1     2
0  1.0  2.0   3.0
1  4.0  2.0   8.0
2  1.0  5.0   9.0
3  7.0  5.0  10.0
4  0.0  2.0   3.0
5  5.0  2.0   8.0
6  7.0  6.0   9.0
7  0.0  8.0  10.0
8  5.0  6.0   3.0
9  7.0  8.0   8.0

关于python - 前向填充上述值 pandas 的 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72184836/

相关文章:

python - 出于测试目的对整个 Django 站点进行密码保护的最明智方法是什么

python - 在单元测试中比较 numpy float 数组

python - Pandas open_excel() 失败,出现 xlrd.biffh.XLRDError : Can't find workbook in OLE2 compound document

python - Pandas DataFrame 构造函数接受列表输入?

scala - Spark Redis连接器可将数据写入Redis的特定索引

r - 从R数据框中删除行

javascript - Django 表单 : How to edit fields that aren't on the model itself

python - 为什么 python 解释器不在 python 模式的 emacs python shell 缓冲区中打印输入代码和输出?

python - 将列堆叠在 pandas 数据透视表中的值标签上方

python - 如何将函数应用于 Pandas 数据框的两列和两个 if 函数