Pandas 如果定义了数据列的限制,则按默认值填充行
我需要根据Pandas 如果定义了数据列的限制,则按默认值填充行,pandas,numpy,dataframe,sign,loc,Pandas,Numpy,Dataframe,Sign,Loc,我需要根据Start和Finish列中的信息,在数据帧中按默认值=1填充行。 因此,在行中填充分隔列的限制是基于['Start','Finish']定义的 数据帧,df1是: ID Car Jan17 Jun18 Dec18 Apr19 Start Finish 0 Nissan 0.0 1.7 3.7 0.0 Jun18 Dec18 1 Porsche
Start
和Finish
列中的信息,在数据帧中按默认值=1
填充行。因此,在行中填充分隔列的限制是基于
['Start','Finish']
定义的
数据帧,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=Jun18
和Finish=Dec18
第0行中的值应由列的1
填充,从Jun18
开始到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
get_dummie
+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
:
如果
Start
和Finish
已经从数据本身派生(似乎是第一列和最后一列非零列),则可以跳过所有虚拟对象,并在原始数据帧上使用where
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())
对于第3行,我不确定Jun18应该是1还是0?@Ben.T,对于第3行
Jun18
应该是1
,因为它是临时损坏的,在0
之后,该过程在Dec18
中继续。这就是为什么使用numpy.sign()
函数会出现问题的原因。现在,这是一个很酷的解决方案+1我不使用插值,但使用pd.date\u范围。很好的解决方案。我认为这比我最初的想法要好。是的,我认为“更安全”的选择是将所有内容转换为datetime
,这样你就可以正确处理丢失的日期。但是似乎Start
和Finish
可能是从要开始的数据中派生出来的,在这种情况下,这将起作用,尽管由于插值的原因,速度很慢。@Alolz,是的,你是对的,我需要在开始日期和结束日期之间填充,并保留任何非零的1
。现在我遇到的问题是,当Start
和Finish
相同时,code返回Start
的插值,直到最后一个现有列,但它应该只将一个值替换为1并停止。例如,我在问题中添加了第6行。。在这种情况下,3.0
应仅在Jun18
列中替换为1,并且不要继续到Apr19
列。Thanks@Cindy抢手货请查看更新。我们需要将limit\u area='inside'
参数添加到interpolation@ALollz,是的,更新后,它会按预期工作。谢谢!
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())