温馨提示:本文翻译自stackoverflow.com,查看原文请点击:pandas - Fill rows by default values if limit for data columns is defined
dataframe loc numpy pandas sign

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

发布于 2020-03-27 10:50:52

我需要=1根据StartFinish列中的信息在DataFrame中填充默认值的行
因此,基于定义行中填充分离列的限制['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行中的值应由填充 1Jun18直到〜为止Dec18

我尝试使用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

查看更多

查看更多

提问者
Cindy
被浏览
122
ALollz 2019-07-04 23:22

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已经从数据本身派生的情况下(似乎是第一列和最后一个非零列),您可以跳过所有虚拟变量,where而在原始DataFrame上使用。

df = df.set_index(['ID', 'Car', 'Start', 'Finish'])
res = (df.where(df.ne(0))
         .clip(1,1)
         .interpolate(axis=1, limit_area='inside')
         .fillna(0, downcast='infer')
         .reset_index())