pd.date_range的视觉返回值不正确(Jupyter Notebook)



出于这样或那样的原因,我想使用pd.date_range 生成的日期来分割数据帧

test=pd.DataFrame(index=pd.date_range(start='2020-01-01',end='2020-06-30',freq='6h'))
test['A']=range(0,len(test),1)
split_list=pd.date_range(start='2020-01-01',end='2020-06-30',freq='m')
display(split_list)
display(test.loc[:'2020-01-31'])
display(test.loc[:split_list[0]])

我本以为这两种方法都会得到相同的结果,但正如你在下面看到的,尽管第一个值显示为"2020-01-31",但实际上它被视为"2020:01-31 00:00:00",导致3个值缺失。

结果

这种行为是故意的吗?

感谢您的帮助!

事实上,这就是预期的行为。";视觉返回";作为日期,因为您在构造pd.date_range时选择了一个高于或等于一天的频率,并且没有特殊时区,但是基本值是Timestamp

在第一种情况下,当您直接通过日期时间的字符串表示(例如"2020-01-31"(进行切片时,Pandas使用它所称的";部分字符串索引";,这本质上是Pandas内置的一种便利,允许您只按特定的年份、月份或日期进行筛选,即使索引是一个完整的DatetimeIndex(在您的情况下,它是(。正如您在链接文档中所看到的,如果您以以下方式进行切片,您将包括最后日期的所有时间戳(行/索引值(:

dft['2013-1':'2013-2-28'] # example from documentation

"这指定了一个停止时间,包括最后一天的所有时间&quot-&gt>2013年1月至2013年2月28日最后一个时间戳的所有时间戳都将包含在选择中。

另一方面,在第二种情况(display(test.loc[:split_list[0]])(中,实际上为切片的结束指定了一个非常具体的时间戳。此时间戳为'2020-01-31 00:00:00',即1月31日的午夜(最早时间(。这意味着该日期的剩余时间戳将被排除在外。

另一种演示方式是使用索引本身进行切片:

## PARTIAL STRING INDEXING
test.loc[:'2020-01-01'] 
#output
A
2020-01-01 00:00:00 0
2020-01-01 06:00:00 1
2020-01-01 12:00:00 2
2020-01-01 18:00:00 3
## STRICT DATETIME INDEXING
test.loc[:test.index[0]]
# output
A
2020-01-01  0

这里发生的情况是,在test.loc[:'2020-01-01']中,'2020-01-01'被解释为日期的字符串表示,而不是日期时间。由于上述Pandas约定,它将筛选所有日期的索引,直到日期'2020-01-01'。因此,您不会丢失该日期中的任何时间戳。

另一方面,test.loc[:test.index[0]]test.index[0]进行比较,后者恰好等于时间戳Timestamp('2020-01-01 00:00:00', freq='6H')。这意味着切片会说";在索引中查找直到时间戳"2020-01-01 00:00:00"(包括该时间戳(的所有日期时间。这意味着1月1日将只选择这一个时间戳。该日期的其他时间戳都发生在午夜之后(请注意,午夜是一天中最早的时间,而不是最晚的时间(。

最后,关于表示:如注释中所述,split_list在您的情况下实际上是DatetimeIndex,因此,尽管当您打印它时,您只看到日期的字符串表示,但它由时间组成。你可以通过打印第一个来看到这一点,例如:

split_list
#output
Timestamp('2020-01-31 00:00:00', freq='M')

由于这是一个频率高于或等于一天的日期范围,因此它将打印为日期,而不是时间戳。

最新更新