英文:
pandas, how only fillna for last row with preceding line closest non-nan value
问题
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0, 10, (10, 10)), columns=list('ABCDEFGHIJ'))
df[df > 5] = np.nan
for i in range(10):
df.iloc[i, i % 10] = np.nan
print(df)
英文:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0, 10, (10, 10)), columns=list('ABCDEFGHIJ'))
df[df > 5] = np.nan
for i in range(10):
df.iloc[i, i % 10] = np.nan
print(df)
origin df is:
A B C D E F G H I J
0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
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:
A B C D E F G H I J
0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
9 0.0 5.0 1.0 2.0 3.0 5.0 2.0 3.0 5.0 5.0
答案1
得分: 5
以下是代码部分的中文翻译:
# 快速解决方案
# 将DataFrame转换为NumPy数组
v = df.values
# 找到每列中最后一个非NaN值的索引
ix = len(df) - 1 - (~np.isnan(v))[::-1].argmax(0)
# 更新DataFrame中最后一行的值
df.iloc[-1, :] = v[ix, range(df.shape[1])]
结果:
A B C D E F G H I J
0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
9 0.0 5.0 1.0 2.0 3.0 5.0 2.0 3.0 5.0 5.0
英文:
Fast solution
v = df.values
ix = len(df) - 1 - (~np.isnan(v))[::-1].argmax(0)
df.iloc[-1, :] = v[ix, range(df.shape[1])]
Result
A B C D E F G H I J
0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
9 0.0 5.0 1.0 2.0 3.0 5.0 2.0 3.0 5.0 5.0
答案2
得分: 2
以下是您要翻译的内容:
df.iloc[-1] = df.ffill().iloc[-1]
print(df)
A B C D E F G H I J
0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
9 0.0 5.0 1.0 2.0 3.0 5.0 2.0 3.0 5.0 5.0
df.loc[df.index[-1], df.iloc[-1].isna()] = df.loc[:, df.iloc[-1].isna()].ffill().iloc[-1]
或者只查找最后一个非NaN值使用 last_valid_index
:
df.iloc[-1] = df.apply(lambda s: s
展开收缩)# 或
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
df.iloc[-1] = df.ffill().iloc[-1]
print(df)
A B C D E F G H I J
0 NaN 2.0 NaN 0.0 5.0 4.0 1.0 NaN NaN 0.0
1 3.0 NaN NaN NaN 2.0 0.0 1.0 1.0 NaN 1.0
2 NaN 5.0 NaN 5.0 NaN 0.0 5.0 0.0 4.0 NaN
3 2.0 NaN NaN NaN 3.0 5.0 NaN NaN NaN 5.0
4 NaN 2.0 NaN 0.0 NaN NaN 2.0 NaN 2.0 0.0
5 NaN NaN NaN 2.0 NaN NaN NaN NaN 0.0 5.0
6 NaN NaN 0.0 NaN 2.0 NaN NaN 1.0 NaN NaN
7 NaN 5.0 1.0 2.0 4.0 NaN 3.0 NaN 3.0 2.0
8 1.0 5.0 1.0 NaN 3.0 NaN 1.0 NaN NaN 5.0
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
.
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
df.iloc[-1] = df.apply(lambda s: s
展开收缩)# or
df.loc[df.index[-1], df.iloc[-1].isna()] = df.loc[:, df.iloc[-1].isna()].apply(lambda s: s
展开收缩)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论