簡體   English   中英

Pandas dataframe 用列中最接近的最小值替換 NaN

[英]Pandas dataframe replace NaN with a nearest minimum value in column

我有一個 pandas dataframe,其中的列名為“A_col”,我想創建一個名為“A_col_fill”的新列,如果有的話,它將用一個最小值替換“A_col”中的 NaN。 示例 output 如下所示。

            A_col           A_col_fill
0            NaN                 NaN
1            NaN                 NaN
2            NaN                 NaN
3            NaN                 NaN
4            NaN                 NaN
5            NaN                 NaN
6            NaN                 NaN
7           -0.3400             -0.3400
8            NaN                -0.3400
9            NaN                -0.3400
10          -0.1900             -0.1900
11            NaN               -0.1900
12          -0.3700             -0.3700
13          -0.4100             -0.4100
14          -0.3300             -0.3300
15            NaN               -0.4100
16            NaN               -0.4100
17            NaN               -0.4100
18            NaN               -0.4100
19            NaN               -0.4100
20          -1.6500             -1.6500
21          -1.8000             -1.8000
22          -1.5300             -1.5300
23          -1.3500             -1.3500
24            NaN               -1.8000
25          -0.1900             -0.1900
26          -0.1400             -0.1400
28          -0.2100             -0.2100

看起來 Dataframe 'fillna' function 不適用於大小寫,我該如何實現它,非常感謝任何代碼片段!

p['A_col'].fillna(np.inf).replace(np.inf,p['A_col'].ffill().cummin())

output:

0      NaN
1      NaN
2      NaN
3      NaN
4      NaN
5      NaN
6      NaN
7    -0.34
8    -0.34
9    -0.34
10   -0.19
11   -0.34
12   -0.37
13   -0.41
14   -0.33
15   -0.41
16   -0.41
17   -0.41
18   -0.41
19   -0.41
20   -1.65
21   -1.80
22   -1.53
23   -1.35
24   -1.80
25   -0.19
26   -0.14
28   -0.21

該解決方案將通過以下內容填充包含值的連續行的最后一個“島”的最小值。 它應該比其他建議的解決方案更准確和更高效(以復雜為代價):

  • 為每個連續值或 nans 的“島”創建一個包含組號的列
  • 獲得每組的最小值; 用前一個最小值向前填充南行
  • 使用新的 min-per-group 列填充原始列

代碼:

df["group_col"] = np.cumsum(df["A_col"].isna() != df["A_col"].isna().shift())
df["group_min"] = df.groupby("group_col").A_col.transform(min).ffill()
df["output"] = df["A_col"].fillna(df.group_min)

結果:

    A_col  A_col_fill  group_col  group_min  output
0     NaN         NaN          1        NaN     NaN
1     NaN         NaN          1        NaN     NaN
2     NaN         NaN          1        NaN     NaN
3     NaN         NaN          1        NaN     NaN
4     NaN         NaN          1        NaN     NaN
5     NaN         NaN          1        NaN     NaN
6     NaN         NaN          1        NaN     NaN
7   -0.34       -0.34          2      -0.34   -0.34
8     NaN       -0.34          3      -0.34   -0.34
9     NaN       -0.34          3      -0.34   -0.34
10  -0.19       -0.19          4      -0.19   -0.19
11    NaN       -0.19          5      -0.19   -0.19
12  -0.37       -0.37          6      -0.41   -0.37
13  -0.41       -0.41          6      -0.41   -0.41
14  -0.33       -0.33          6      -0.41   -0.33
15    NaN       -0.41          7      -0.41   -0.41
16    NaN       -0.41          7      -0.41   -0.41
17    NaN       -0.41          7      -0.41   -0.41
18    NaN       -0.41          7      -0.41   -0.41
19    NaN       -0.41          7      -0.41   -0.41
20  -1.65       -1.65          8      -1.80   -1.65
21  -1.80       -1.80          8      -1.80   -1.80
22  -1.53       -1.53          8      -1.80   -1.53
23  -1.35       -1.35          8      -1.80   -1.35
24    NaN       -1.80          9      -1.80   -1.80
25  -0.19       -0.19         10      -0.21   -0.19
26  -0.14       -0.14         10      -0.21   -0.14
28  -0.21       -0.21         10      -0.21   -0.21

在我的機器上,1M 行 df 的解決方案需要幾毫秒:

df = pd.DataFrame(np.random.random(size=100000), columns=["A_col"])
df.loc[df.sample(frac=0.6).index, "A_col"] = np.nan
# code from above
df["group_col"] = np.cumsum(df["A_col"].isna() != df["A_col"].isna().shift())
df["group_min"] = df.groupby("group_col").A_col.transform(min).ffill()
df["output"] = df["A_col"].fillna(df.group_min)

簡單的解決方案,只需遍歷該列並始終保持最小值並填充 Nan 值

def fill_min(df):
  minx = np.inf
  ans = []
  for val in df['A_Col']:
    if np.isnan(val):
      ans.append(val if np.isinf(minx) else minx)
    else:
      minx = min(minx, val)
      ans.append(val)
  return ans

采用:

df['A_col_fill'] = fill_min(df)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM