如何按DateTime列过滤Microsoft.Data.Analysis.DataFrame并解决异常
异常原因
0.18.0版本的Microsoft.Data.Analysis包仅对数值、字符串等常用类型实现了ElementwiseEquals这类逐元素比较方法,未针对DateTime类型的PrimitiveDataFrameColumn做对应逻辑适配,所以调用该方法时会直接抛出System.NotSupportedException异常。
正确过滤方案
可通过以下两种方式实现DateTime类型列的过滤,无需升级包版本即可兼容0.18.0版本:
- 方案1:将DateTime转换为Ticks时间戳后比较
该方案性能更高,适合数据量较大的场景:
DateTime[] birthdays = {DateTime.Parse("4/23/1990"), DateTime.Parse("4/5/1982"), DateTime.Parse("2/1/1980"), DateTime.Parse("9/10/1994") }; var birthdayColumn = new PrimitiveDataFrameColumn<DateTime>("Birthday", birthdays); var df = new DataFrame(birthdayColumn); long targetTimeStamp = DateTime.Parse("4/5/1982").Ticks; // 将DateTime列逐元素转换为Ticks长整型列 var timeStampColumn = birthdayColumn.Elementwise<long>(date => date.Ticks); var filter = timeStampColumn.ElementwiseEquals(targetTimeStamp); var theBirthday = df.Filter(filter);
- 方案2:遍历行生成布尔过滤列
该方案灵活性更高,支持更复杂的DateTime判断逻辑(比如按年份、月份单独筛选):
DateTime[] birthdays = {DateTime.Parse("4/23/1990"), DateTime.Parse("4/5/1982"), DateTime.Parse("2/1/1980"), DateTime.Parse("9/10/1994") }; var birthdayColumn = new PrimitiveDataFrameColumn<DateTime>("Birthday", birthdays); var df = new DataFrame(birthdayColumn); DateTime target = DateTime.Parse("4/5/1982"); var filterColumn = new PrimitiveDataFrameColumn<bool>("Filter", df.Rows.Count); for (int i = 0; i < df.Rows.Count; i++) { filterColumn[i] = (DateTime)df.Rows[i]["Birthday"] == target; } var theBirthday = df.Filter(filterColumn);
如果允许升级依赖包版本,可将Microsoft.Data.Analysis升级到0.20.0及以上版本,该版本已完整支持DateTime类型的逐元素比较操作,你给出的原始代码可直接正常运行。
内容的提问来源于stack exchange,提问作者D. Reagan
相关产品推荐
相关产品推荐

