使用 pandas 从基于时间的列中选择最新值

use pandas to pick latest value from time based columns

我有如下所示的 DataFrame

ID_1,time_1,time_2       
1,21,0
1,31,5
1,0,0
1,21,100
1,21,21
2,202,0
2,310,
2,0,0
2,201,
2,210,
2,178,190

我想获取来自 time_2 列的最新值。

但是,每当 time_2 列为零或为空时,我想从 time_1 列中选取值。

如果 time_1time_2 都为零,那么我们只输入 0。

我正在尝试类似下面的操作

tdf['latest_value'] = tdf['time_2']
tdf['time_2'] = np.where((tdf['time_2']==0 | tdf['time_2'].isna()==True),tdf['time_1'],tdf['time_2'])

我希望我的输出如下所示

0 值替换为缺失值,用另一列替换缺失值:

tdf['latest_value'] = tdf['time_2'].replace(0, np.nan).fillna(tdf['time_1'])
print (tdf)
    ID_1  time_1  time_2  latest_value
0      1      21     0.0          21.0
1      1      31     5.0           5.0
2      1       0     0.0           0.0
3      1      21   100.0         100.0
4      1      21    21.0          21.0
5      2     202     0.0         202.0
6      2     310     NaN         310.0
7      2       0     0.0           0.0
8      2     201     NaN         201.0
9      2     210     NaN         210.0
10     2     178   190.0         190.0

或者如果可能的话,首先替换许多列,向前填充缺失值,然后 select 最后一列将缺失值替换为 0:

c = ['time_1', 'time_2']
tdf['latest_value'] = tdf[c].replace(0, np.nan).ffill(axis=1).iloc[:, -1].fillna(0)
print (tdf)
    ID_1  time_1  time_2  latest_value
0      1      21     0.0          21.0
1      1      31     5.0           5.0
2      1       0     0.0           0.0
3      1      21   100.0         100.0
4      1      21    21.0          21.0
5      2     202     0.0         202.0
6      2     310     NaN         310.0
7      2       0     0.0           0.0
8      2     201     NaN         201.0
9      2     210     NaN         210.0
10     2     178   190.0         190.0

您可以使用 maskfillna(或 combine_first):

tdf['latest_value']=tdf['time_2'].mask(df['time_2'] == 0).fillna(tdf['time_1'])

# OR

tdf['latest_value']=tdf['time_2'].mask(df['time_2'] == 0).combine_first(df['time_1'])

输出:

    ID_1  time_1  time_2  latest_value
0      1      21     0.0          21.0
1      1      31     5.0           5.0
2      1       0     0.0           0.0
3      1      21   100.0         100.0
4      1      21    21.0          21.0
5      2     202     0.0         202.0
6      2     310     NaN         310.0
7      2       0     0.0           0.0
8      2     201     NaN         201.0
9      2     210     NaN         210.0
10     2     178   190.0         190.0

numpy.where 也适用于此。在您的代码中,您只是缺少一个括号,因为 | 的优先级高于 ==:

tdf['latest_value'] = np.where((tdf['time_2']==0) | tdf['time_2'].isna(), tdf['time_1'], tdf['time_2'])

输出:

    ID_1  time_1  time_2  latest_value
0      1      21     0.0          21.0
1      1      31     5.0           5.0
2      1       0     0.0           0.0
3      1      21   100.0         100.0
4      1      21    21.0          21.0
5      2     202     0.0         202.0
6      2     310     NaN         310.0
7      2       0     0.0           0.0
8      2     201     NaN         201.0
9      2     210     NaN         210.0
10     2     178   190.0         190.0