Как удалить первую и последнюю строки с NaN из кадра данных и заменить оставшийся NaN средним значением ниже и выше? - PullRequest
4 голосов
/ 21 апреля 2020

Давайте возьмем этот фрейм данных в качестве простого примера:

df = pd.DataFrame(dict(Col1=[np.nan,1,1,2,3,8,7], Col2=[1,1,np.nan,np.nan,3,np.nan,4], Col3=[1,1,np.nan,5,1,1,np.nan]))

   Col1  Col2  Col3
0   NaN   1.0   1.0
1   1.0   1.0   1.0
2   1.0   NaN   NaN
3   2.0   NaN   5.0
4   3.0   3.0   1.0
5   8.0   NaN   1.0
6   7.0   4.0   NaN

Я хотел бы сначала удалить первую и последнюю строки, пока в первой и последней строке больше не будет NaN.

Промежуточный ожидаемый результат:

   Col1  Col2  Col3
1   1.0   1.0   1.0
2   1.0   NaN   NaN
3   2.0   NaN   5.0
4   3.0   3.0   1.0

Затем я хотел бы заменить оставшийся NaN средним значением ближайшего значения, ниже которого не является NaN, и тот, что выше.

Окончательный ожидаемый результат:

   Col1  Col2  Col3
0   1.0   1.0   1.0
1   1.0   2.0   3.0
2   2.0   2.0   5.0
3   3.0   3.0   1.0

Я знаю, что у меня могут быть позиции NaN в моем кадре данных через

df.isna()

Но я могу не решить мою проблему. Как, пожалуйста, я мог сделать?

Ответы [ 2 ]

3 голосов
/ 21 апреля 2020

Мой подход:

# identify the rows with some NaN
s = df.notnull().all(1)

# remove those with NaN at beginning and at the end:
new_df = df.loc[s.idxmax():s[::-1].idxmax()]

# average:
new_df = (new_df.ffill()+ new_df.bfill())/2

Вывод:

   Col1  Col2  Col3
1   1.0   1.0   1.0
2   1.0   2.0   3.0
3   2.0   2.0   5.0
4   3.0   3.0   1.0
2 голосов
/ 21 апреля 2020

Другой вариант - использовать DataFrame.interpolate с round:

nans = df.notna().all(axis=1).cumsum().drop_duplicates()
low, high = nans.idxmin(), nans.idxmax()

df.loc[low+1: high].interpolate().round()

   Col1  Col2  Col3
1   1.0   1.0   1.0
2   1.0   2.0   3.0
3   2.0   2.0   5.0
4   3.0   3.0   1.0
...