2014-09-18 3 views
13

Я новичок в Python и Pandas, поэтому может быть простое решение, которое я не вижу.Отсутствующие данные, вставьте строки в Pandas и заполните NAN

У меня есть ряд прерывистых наборов данных, которые выглядят следующим образом:

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 варьируется от набора данных к набору данных в позиции и длине ...

+0

Добро пожаловать в StackOverflow. Пожалуйста, убедитесь, что вы показываете свой код (усилие) другим пользователям, чтобы они хорошо понимали вашу проблему и могли отлаживать ее. –

ответ

15

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]}) 

Первого ход колонок А индекс:

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 
+0

Спасибо, это работает отлично. – mati

1

В этом случае я переписываю ваш столбец 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 но не уронить его, а затем индексировать ФР с помощью функции arange.

1

Используя ответ на 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) 
Смежные вопросы