如果定义了数据列的限制,则使用默认值填充行

时间:2019-07-03 14:03:26

标签: pandas numpy dataframe sign loc

我需要根据=1Start列中的信息填充DataFrame中默认值为Finish的行。
因此,基于['Start', 'Finish']定义了行中填充独立列的限制。

DataFrame,df1是:

ID  Car       Jan17     Jun18  Dec18  Apr19   Start   Finish                           
0   Nissan     0.0       1.7    3.7    0.0    Jun18   Dec18   
1   Porsche    10.0      0.0    2.8    3.5    Jan17   Apr19 
2   Golf       0.0       1.7    3.0    2.0    Jun18   Apr19 
3   Toyota     1.0       0.0    3.0    5.2    Jan17   Apr19 
4   Mazda      0.0       0.0    3.0    4.2    Dec18   Apr19
5   Mercedes   0.0       0.0    0.0    7.2    Apr19   Apr19
6   Passat     0.0       3.0    0.0    0.0    Jun18   Jun18

例如,如果存在第0行: Start = Jun18Finish = Dec18

第0行的值应由1填充,从Jun18Dec18为止。

我尝试使用numpy.sign()函数,但是如果0.0在两个非零值之间,则会出现错误的结果。

预期结果为df2

ID  Car       Jan17     Jun18  Dec18  Apr19   Start   Finish                           
0   Nissan     0.0       1.0    1.0    0.0    Jun18   Dec18   
1   Porsche    1.0       1.0    1.0    1.0    Jan17   Apr19 
2   Golf       0.0       1.0    1.0    1.0    Jun18   Apr19 
3   Toyota     1.0       1.0    1.0    1.0    Jan17   Apr19 
4   Mazda      0.0       0.0    1.0    1.0    Dec18   Apr19
5   Mercedes   0.0       0.0    0.0    1.0    Apr19   Apr19
6   Passat     0.0       1.0    0.0    0.0    Jun18   Jun18

1 个答案:

答案 0 :(得分:3)

get_dummies + interpolate

这要求您的列要按时间顺序排序,并且理想情况下,开始和结束必须始终存在于列名称中。

df = df.set_index(['ID', 'Car', 'Start', 'Finish'])

s1 = (pd.get_dummies(df.index.get_level_values('Start'))
        .reindex(df.columns, axis=1)
        .replace(0, np.NaN))
s2 = (pd.get_dummies(df.index.get_level_values('Finish'))
        .reindex(df.columns, axis=1)
        .replace(0, np.NaN))

res = s1.combine_first(s2).interpolate(axis=1, limit_area='inside').fillna(0, downcast='infer')
res.index = df.index
res = res.reset_index()

输出res

   ID       Car  Start Finish  Jan17  Jun18  Dec18  Apr19
0   0    Nissan  Jun18  Dec18      0      1      1      0
1   1   Porsche  Jan17  Apr19      1      1      1      1
2   2      Golf  Jun18  Apr19      0      1      1      1
3   3    Toyota  Jan17  Apr19      1      1      1      1
4   4     Mazda  Dec18  Apr19      0      0      1      1
5   5  Mercedes  Apr19  Apr19      0      0      0      1
6   6    Passat  Jun18  Jun18      0      1      0      0

如果StartFinish已经从数据本身派生了(似乎是第一个和最后一个非零列),则可以跳过所有虚拟变量并使用{{ 1}},而不是原始的DataFrame。

where