2

我有以下数据框:

import pandas as pd
df = pd.DataFrame({
    'col1':['A',pd.NA,pd.NA,pd.NA,pd.NA, 'B', pd.NA, pd.NA],
    'col2':[9.5, 6,24,8, 30, 7, 6, 8],
    })
print(df)

给予:

   col1  col2
0     A   9.5
1  <NA>   6.0
2  <NA>  24.0
3  <NA>   8.0
4  <NA>  30.0
5     B   7.0
6  <NA>   6.0
7  <NA>   8.0

我想要实现的是前向填充 col1,但不是在 col2 中的值大于我从中前向填充的行的 col2 值的行中。像这样:

   col1  col2
0     A   9.5
1     A   6.0
2  <NA>  24.0
3     A   8.0
4  <NA>  30.0
5     B   7.0
6     B   6.0
7  <NA>   8.0

这里,索引 1 和 3 是前向填充的,但索引 2 和 4 不是,因为 col2 值 (24, 30) 大于初始行的 col2 值 (9.5)

我可以通过迭代df来达到预期的结果,如下所示:

val2 = -1
for i, r in df.iterrows():
    if not pd.isnull(r['col1']):
        val1 = r['col1']
        val2 = r['col2']
    else:
        if r['col2']<val2:
            df.loc[i, 'col1'] = val1
print(df)

有没有办法在不使用 iterrows() 的情况下实现这一点?

4

2 回答 2

3

您可以将填充缺失值转发给辅助系列s,然后按此系列比较组 - 所有值的第一个值,如果值不是更大的替换值numpy.where

s = df['col1'].ffill()

df['col1'] = np.where(df.groupby(s)['col2'].transform('first').gt(df['col2']),s,df['col1'])
print (df)
   col1  col2
0     A   9.5
1     A   6.0
2  <NA>  24.0
3     A   8.0
4  <NA>  30.0
5     B   7.0
6     B   6.0
7  <NA>   8.0
于 2022-02-10T08:31:51.543 回答
0

您也可以将“col1”按非NaN值分组,得到first对应的“col2”值并进行变换;然后将其与“col2”进行比较以创建一个布尔掩码(“col2”值小于填充符的“col2”值的行)。然后ffill将那些被这个面具抓住的人与那些没有被它抓住的人连接起来。

msk = df.groupby(df['col1'].notna().cumsum())['col2'].transform('first') >= df['col2']
df = pd.concat((df[msk].ffill(), df[~msk])).sort_index()

输出:

  col1  col2
0    A   9.5
1    A   6.0
2  NaN  24.0
3    A   8.0
4  NaN  30.0
5    B   7.0
6    B   6.0
7  NaN   8.0
于 2022-02-10T08:43:07.307 回答