Недостающие данные, вставьте строки в Pandas и заполните NAN
Я новичок в Python и Pandas, так что может быть простое решение, которое я не вижу.
У меня есть несколько прерывистых наборов данных, которые выглядят так:
ind A B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 3.5 2 0
4 4.0 4 5
5 4.5 3 3
Я сейчас ищу решение, чтобы получить следующее:
ind A B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 1.5 NAN NAN
4 2.0 NAN NAN
5 2.5 NAN NAN
6 3.0 NAN NAN
7 3.5 2 0
8 4.0 4 5
9 4.5 3 3
Проблема заключается в том, что разрыв в A варьируется от набора данных к набору данных по положению и длине...
3 ответа
set_index
а также reset_index
твои друзья.
df = DataFrame({"A":[0,0.5,1.0,3.5,4.0,4.5], "B":[1,4,6,2,4,3], "C":[3,2,1,0,5,3]})
Сначала переместите столбец A в индекс:
In [64]: df.set_index("A")
Out[64]:
B C
A
0.0 1 3
0.5 4 2
1.0 6 1
3.5 2 0
4.0 4 5
4.5 3 3
Затем переиндексация с новым индексом, здесь недостающие данные заполняются с помощью nans. Мы используем Index
объект, так как мы можем назвать его; это будет использовано на следующем шаге.
In [66]: new_index = Index(arange(0,5,0.5), name="A")
In [67]: df.set_index("A").reindex(new_index)
Out[67]:
B C
0.0 1 3
0.5 4 2
1.0 6 1
1.5 NaN NaN
2.0 NaN NaN
2.5 NaN NaN
3.0 NaN NaN
3.5 2 0
4.0 4 5
4.5 3 3
Наконец, переместите индекс обратно в столбцы с reset_index
, Поскольку мы назвали индекс, все работает волшебным образом:
In [69]: df.set_index("A").reindex(new_index).reset_index()
Out[69]:
A B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 1.5 NaN NaN
4 2.0 NaN NaN
5 2.5 NaN NaN
6 3.0 NaN NaN
7 3.5 2 0
8 4.0 4 5
9 4.5 3 3
Используя ответ EdChum выше, я создал следующую функцию
def fill_missing_range(df, field, range_from, range_to, range_step=1, fill_with=0):
return df\
.merge(how='right', on=field,
right = pd.DataFrame({field:np.arange(range_from, range_to, range_step)}))\
.sort_values(by=field).reset_index().fillna(fill_with).drop(['index'], axis=1)
Пример использования:
fill_missing_range(df, 'A', 0.0, 4.5, 0.5, np.nan)
В этом случае я перезаписываю ваш столбец A новым сгенерированным кадром данных и объединяю его с вашим исходным df, затем я прибегаю к нему:
In [177]:
df.merge(how='right', on='A', right = pd.DataFrame({'A':np.arange(df.iloc[0]['A'], df.iloc[-1]['A'] + 0.5, 0.5)})).sort(columns='A').reset_index().drop(['index'], axis=1)
Out[177]:
A B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 1.5 NaN NaN
4 2.0 NaN NaN
5 2.5 NaN NaN
6 3.0 NaN NaN
7 3.5 2 0
8 4.0 4 5
9 4.5 3 3
Так что в общем случае вы можете настроить arange
функция, которая принимает начальное и конечное значение, заметьте, я добавил 0,5 к концу, так как диапазоны открыты закрыты и передают значение шага.
Более общий метод может быть таким:
In [197]:
df = df.set_index(keys='A', drop=False).reindex(np.arange(df.iloc[0]['A'], df.iloc[-1]['A'] + 0.5, 0.5))
df.reset_index(inplace=True)
df['A'] = df['index']
df.drop(['A'], axis=1, inplace=True)
df.reset_index().drop(['level_0'], axis=1)
Out[197]:
index B C
0 0.0 1 3
1 0.5 4 2
2 1.0 6 1
3 1.5 NaN NaN
4 2.0 NaN NaN
5 2.5 NaN NaN
6 3.0 NaN NaN
7 3.5 2 0
8 4.0 4 5
9 4.5 3 3
Здесь мы устанавливаем индекс для столбца A
но не бросайте его, а затем переиндексируйте df, используя arange
функция.
Этот вопрос был задан давно, но у меня есть простое решение, о котором стоит упомянуть. Вы можете просто использовать NaN NumPy. Например:
import numpy as np
df[i,j] = np.NaN
сделает свое дело.