Фрейм данных df содержит много тысяч столбцов и строк. Для подмножества столбцов, заданных в определенной последовательности, например, столбцы B, C, E, я хочу заполнить NaN значения в B первым не-NaN-значением, найденным в остальных столбцах ({{ X4}}) поиск последовательно. Наконец C, E отброшены

Образец df может быть построен следующим образом:

import numpy as np
import pandas as pd
df = pd.DataFrame(10*(2+np.random.randn(6, 5)), columns=list('ABCDE'))
df.loc[1, 'B'] = np.nan
df.loc[2, 'B'] = np.nan
df.loc[5, 'B'] = np.nan
df.loc[2, 'C'] = np.nan
df.loc[5, 'C'] = np.nan
df.loc[2, 'D'] = np.nan
df.loc[2, 'E'] = np.nan
df.loc[4, 'E'] = np.nan
df
           A         B          C          D          E
0  18.161033  6.453597  25.253036  18.542586  20.667311
1  27.629402       NaN  40.654821  22.804547  23.633502
2  15.459256       NaN        NaN        NaN        NaN
3  19.115203  4.002131  14.167508  23.796780  29.557706
4  27.180622       NaN  20.763618  15.923794        NaN
5  17.917170       NaN        NaN  21.865184   9.867743

Ожидаемый результат выглядит следующим образом:

           A         B         D
0  18.161033  6.453597 18.542586
1  27.629402 40.654821 22.804547
2  15.459256       NaN       NaN
3  19.115203  4.002131 23.796780
4  27.180622 20.763618 15.923794
5  17.917170  9.867743 21.865184
2
Gerry 14 Апр 2019 в 03:12

2 ответа

Лучший ответ

Вот один способ

drop = ['C', 'E']
fill= 'B'
d=dict(zip(df.columns,[fill if x in drop else x for x in df.columns.tolist() ]))
df.groupby(d,axis=1).first()
Out[172]: 
           A          B          D
0  14.472915  30.598602  24.528571
1  22.010242  22.215140  15.412039
2   5.383674        NaN        NaN
3  38.265940  24.746673  35.367622
4  22.730089  20.244289  27.570413
5  31.216037  15.496690   9.746814
2
YO and BEN_W 14 Апр 2019 в 00:33

IIUC, используйте bfill для обратной засыпки, затем drop для удаления ненужных столбцов.

df.assign(B=df[['B', 'C', 'E']].bfill(axis=1)['B']).drop(['C', 'E'], axis=1)

           A          B          D
0  18.161033   6.453597  18.542586
1  27.629402  40.654821  22.804547
2  15.459256        NaN        NaN
3  19.115203   4.002131  23.796780
4  27.180622  20.763618  15.923794
5  17.917170   9.867743  21.865184

Вот немного более обобщенная версия приведенной выше,

to_drop = ['C', 'E']
upd = 'B'

df.update(df[[upd, *to_drop]].bfill(axis=1)[upd])  # in-place
df.drop(to_drop, axis=1)                           # not in-place, need to assign

           A          B          D
0  18.161033   6.453597  18.542586
1  27.629402  40.654821  22.804547
2  15.459256        NaN        NaN
3  19.115203   4.002131  23.796780
4  27.180622  20.763618  15.923794
5  17.917170   9.867743  21.865184
2
cs95 14 Апр 2019 в 00:17