fillna 只用于最后一行,用最接近的上一行非 NaN 值填充。

huangapple go评论165阅读模式
英文:

pandas, how only fillna for last row with preceding line closest non-nan value

问题

  1. import pandas as pd
  2. import numpy as np
  3. df = pd.DataFrame(np.random.randint(0, 10, (10, 10)), columns=list('ABCDEFGHIJ'))
  4. df[df > 5] = np.nan
  5. for i in range(10):
  6. df.iloc[i, i % 10] = np.nan
  7. print(df)
英文:
  1. import pandas as pd
  2. import numpy as np
  3. df = pd.DataFrame(np.random.randint(0, 10, (10, 10)), columns=list('ABCDEFGHIJ'))
  4. df[df > 5] = np.nan
  5. for i in range(10):
  6. df.iloc[i, i % 10] = np.nan
  7. print(df)

origin df is:

  1. A B C D E F G H I J
  2. 0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
  3. 1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
  4. 2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
  5. 3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
  6. 4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
  7. 5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
  8. 6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
  9. 7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
  10. 8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
  11. 9 0.0 NaN NaN NaN 3.0 NaN 2.0 3.0 5.0 NaN

I only want to fillna for last row with preceding line closest non-nan value, I hava a big dataframe, so I want ot use the fastest way to save the most memory, to become to:

  1. A B C D E F G H I J
  2. 0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
  3. 1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
  4. 2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
  5. 3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
  6. 4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
  7. 5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
  8. 6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
  9. 7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
  10. 8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
  11. 9 0.0 5.0 1.0 2.0 3.0 5.0 2.0 3.0 5.0 5.0

答案1

得分: 5

以下是代码部分的中文翻译:

  1. # 快速解决方案
  2. # 将DataFrame转换为NumPy数组
  3. v = df.values
  4. # 找到每列中最后一个非NaN值的索引
  5. ix = len(df) - 1 - (~np.isnan(v))[::-1].argmax(0)
  6. # 更新DataFrame中最后一行的值
  7. df.iloc[-1, :] = v[ix, range(df.shape[1])]

结果:

  1. A B C D E F G H I J
  2. 0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
  3. 1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
  4. 2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
  5. 3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
  6. 4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
  7. 5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
  8. 6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
  9. 7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
  10. 8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
  11. 9 0.0 5.0 1.0 2.0 3.0 5.0 2.0 3.0 5.0 5.0
英文:

Fast solution

  1. v = df.values
  2. ix = len(df) - 1 - (~np.isnan(v))[::-1].argmax(0)
  3. df.iloc[-1, :] = v[ix, range(df.shape[1])]

Result

  1. A B C D E F G H I J
  2. 0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
  3. 1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
  4. 2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
  5. 3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
  6. 4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
  7. 5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
  8. 6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
  9. 7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
  10. 8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
  11. 9 0.0 5.0 1.0 2.0 3.0 5.0 2.0 3.0 5.0 5.0

答案2

得分: 2

以下是您要翻译的内容:

  1. df.iloc[-1] = df.ffill().iloc[-1]
  1. print(df)
  2. A B C D E F G H I J
  3. 0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
  4. 1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
  5. 2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
  6. 3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
  7. 4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
  8. 5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
  9. 6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
  10. 7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
  11. 8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
  12. 9 0.0 5.0 1.0 2.0 3.0 5.0 2.0 3.0 5.0 5.0
  1. df.loc[df.index[-1], df.iloc[-1].isna()] = df.loc[:, df.iloc[-1].isna()].ffill().iloc[-1]

或者只查找最后一个非NaN值使用 last_valid_index

  1. df.iloc[-1] = df.apply(lambda s: s
    展开收缩
    )
  2. # 或
  3. df.loc[df.index[-1], df.iloc[-1].isna()] = df.loc[:, df.iloc[-1].isna()].apply(lambda s: s
    展开收缩
    )
英文:

You can do a forward fill and assign the last row

  1. df.iloc[-1] = df.ffill().iloc[-1]
  1. print(df)
  2. A B C D E F G H I J
  3. 0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
  4. 1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
  5. 2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
  6. 3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
  7. 4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
  8. 5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
  9. 6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
  10. 7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
  11. 8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
  12. 9 0.0 5.0 1.0 2.0 3.0 5.0 2.0 3.0 5.0 5.0

You can also consider filter column where the last row is not NaN.

  1. df.loc[df.index[-1], df.iloc[-1].isna()] = df.loc[:, df.iloc[-1].isna()].ffill().iloc[-1]

Or only find the last non nan value with last_valid_index

  1. df.iloc[-1] = df.apply(lambda s: s
    展开收缩
    )
  2. # or
  3. df.loc[df.index[-1], df.iloc[-1].isna()] = df.loc[:, df.iloc[-1].isna()].apply(lambda s: s
    展开收缩
    )

huangapple
  • 本文由 发表于 2023年3月12日 13:51:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75711280.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定