Pandas DataFrame: как заполнить `nan` нулями, но между действительными значениями существуют только nans? - PullRequest
3 голосов
/ 19 октября 2019

Что я хотел бы сделать:

In [2]: b = pd.DataFrame({"a": [np.nan, 1, np.nan, 2, np.nan]})
Out[2]:
      a
0   nan
1 1.000
2   nan
3 2.000
4   nan

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

      a
0   nan
1 1.000
2   0
3 2.000
4   nan

Как вы можете видеть здесь, только наны, которые окружены действительными значениями, заменяются на 0.

Как я могу это сделать?

  • df.interpolate(limit_area='inside') выглядит хорошо для меня, но у него нет аргумента для заполнения нулями ...

Ответы [ 2 ]

3 голосов
/ 19 октября 2019

Метод 1: interpolate, isna, notna и loc

Вы можете использовать interpolate, а затем проверить, какие позиции имеют NaN в ваших исходных данных, а какиезаполните ваши интерполированные значения, затем замените эти значения на 0:

s = df['a'].interpolate(limit_area='inside')

m1 = b['a'].isna()
m2 = s.notna()

df.loc[m1&m2, 'a'] = 0

     a
0  NaN
1  1.0
2  0.0
3  2.0
4  NaN

Метод 2: shift и loc:

Более простым способом будет проверкаесли предыдущая строка и следующая строка not NaN и заполните эти позиции с помощью 0:

m1 = df['a'].shift().notna()
m2 = df['a'].shift(-1).notna()
m3 = df['a'].isna()

df.loc[m1&m2&m3, 'a'] = 0

     a
0  NaN
1  1.0
2  0.0
3  2.0
4  NaN
0 голосов
/ 19 октября 2019
b = pd.DataFrame({"a": [np.nan, 1, np.nan, 2, np.nan,3,np.nan]})
a = b[b['a'].isna()]
print('After :',b['a'])

#######Solution One######
for x in a.iterrows() :
    pre = x[0] - 1
    post = x[0]  +1
    if pre < 0 or post >= len(b['a']) :
        pass
    else :
        if  not(np.isnan(b.iloc[pre,0])) and not(np.isnan(b.iloc[post,0])) :
            b.iloc[x[0],0] = 0


print('Before :',b['a'])

######Solution Two#######
def series_extract(index, series):
    return map(np.isnan, series[[index-1, index, index+1]])

def fill_in_between_na(df, column):
    series = df[column]
    index = []
    for i in range(1,len(series)-1) :
        mask = np.array([False,True,False]) == np.array(series_extract(i, series))
        if all(mask):
            index.append(i)
    df[column][index] = 0
    return df

fill_in_between_na(b, 'a')
print('Before :',b['a'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...