Переместить нулевые строки в нижнюю часть фрейма данных

#python #python-3.x #pandas #numpy #dataframe

#python #python-3.x #pandas #numpy #фрейм данных

Вопрос:

У меня есть фрейм данных:

 df1 = pd.DataFrame({'a': [1, 2, 10, np.nan, 5, 6, np.nan, 8],
                   'b': list('abcdefgh')})
df1

     a      b
0   1.0     a
1   2.0     b
2   10.0    c
3   NaN     d
4   5.0     e
5   6.0     f
6   NaN     g
7   8.0     h
  

Я хотел бы переместить все строки, где a равно np.nan, в нижнюю часть фрейма данных

 df2 = pd.DataFrame({'a': [1, 2, 10, 5, 6, 8, np.nan,  np.nan],
                   'b': list('abcefhdg')})
df2

     a      b
0   1.0     a
1   2.0     b
2   10.0    c
3   5.0     e
4   6.0     f
5   8.0     h
6   NaN     d
7   NaN     g
  

Я пробовал это:

 na = df1[df1.a.isnull()]
df1.dropna(subset = ['a'], inplace=True)
df1 = df1.append(na)
df1
  

Есть ли более чистый способ сделать это? Или есть функция, которую я могу использовать для этого?

Комментарии:

1. Вам нужна сортировка или перемещение?

2. Мне нужно переместить значения

3. Хорошо, значит sort_values , нельзя использовать, верно?

4. Может быть, лучше изменить данные, чтобы не путать других людей 🙂

5. Это действительно сбивает с толку. Его вывод выглядит как sort_values с na_position

Ответ №1:

Новый ответ после редактирования OP

Вы были близки к этому, но вы можете немного очистить свой код, используя следующее:

 df1 = pd.concat([df1[df1['a'].notnull()], df1[df1['a'].isnull()]], ignore_index=True)

print(df1)
      a  b
0   1.0  a
1   2.0  b
2  10.0  c
3   5.0  e
4   6.0  f
5   8.0  h
6   NaN  d
7   NaN  g
  

Старый ответ
Использовать sort_values с na_position=last аргументом:

 df1 = df1.sort_values('a', na_position='last')

print(df1)
     a  b
0  1.0  a
1  2.0  b
2  3.0  c
4  5.0  e
5  6.0  f
7  8.0  h
3  NaN  d
6  NaN  g
  

Комментарии:

1. Новое решение похоже на мое, но определенно намного чище. Спасибо

Ответ №2:

pandas Пока не существует, используйте Series.isna with Series.argsort для позиций и измените порядок на DataFrame.iloc :

 df1 = df1.iloc[df1['a'].isna().argsort()].reset_index(drop=True)
print (df1)
      a  b
0   1.0  a
1   2.0  b
2  10.0  c
3   5.0  e
4   6.0  f
5   8.0  h
6   NaN  d
7   NaN  g
  

Или чистое решение pandas со вспомогательным столбцом и DataFrame.sort_values :

 df1 = (df1.assign(tmp=df1['a'].isna())
          .sort_values('tmp')
          .drop('tmp', axis=1)
          .reset_index(drop=True))
print (df1)
      a  b
0   1.0  a
1   2.0  b
2  10.0  c
3   5.0  e
4   6.0  f
5   8.0  h
6   NaN  d
7   NaN  g