使用 .loc 函数错误的 Pandas DataFrame 时间索引

Posted

技术标签:

【中文标题】使用 .loc 函数错误的 Pandas DataFrame 时间索引【英文标题】:Pandas DataFrame Time index using .loc function error 【发布时间】:2021-10-30 10:31:33 【问题描述】:

我创建了带有 DateTime 索引的 DataFrame,然后我将索引拆分为 Date 索引列和 Time 索引列。现在,当我使用 pd.loc() 调用特定时间的一行时,系统显示错误。

这里是我如何制作 DataFrame 的步骤示例,从开始到达到我的考虑。

import pandas as pd
import numpy as np

df= pd.DataFrame('A':[1, 2, 3, 4], 'B':[5, 6, 7, 8], 'C':[9, 10, 11, 12],
    'DateTime':pd.to_datetime(['2021-09-01 10:00:00', '2021-09-01 11:00:00', '2021-09-01 12:00:00', '2021-09-01 13:00:00']))

df=df.set_index(df['DateTime'])
df.drop('DateTime', axis=1, inplace=True)
df

输出>>

                    A   B   C
DateTime            
2021-09-01 10:00:00 1   5   9
2021-09-01 11:00:00 2   6   10
2021-09-01 12:00:00 3   7   11
2021-09-01 13:00:00 4   8   12

在这一步中,我要将 DateTime 索引拆分为多索引日期和时间

df.index = pd.MultiIndex.from_arrays([df.index.date, df.index.time], names=['Date','Time'])
df

输出>>

                        A   B   C
     Date   Time            
2021-09-01  10:00:00    1   5   9
            11:00:00    2   6   10
            12:00:00    3   7   11
            13:00:00    4   8   12

##问题出在这里##

当我调用这个语句时,系统显示错误

df.loc["11:00:00"]

如何解决?

【问题讨论】:

那么你想从每个日期中选择每个11:00:00 吗? 【参考方案1】:

1。如果你想使用.loc,你可以指定时间:

import datetime

df.loc[(slice(None), datetime.time(11, 0)), :]

或者使用pd.IndexSlice类似BENY的解决方案,如下:

import datetime

idx = pd.IndexSlice
df.loc[idx[:,datetime.time(11, 0)], :]

(如果您要多次使用pd.IndexSlice,定义一个变量idx 以使用pd.IndexSlice 可以让我们的代码更简洁,输入更少)。

结果:

                     A  B   C
Date       Time              
2021-09-01 11:00:00  2  6  10

2。如果您只想选择一天,您可以使用:

import datetime

df.loc[(datetime.date(2021, 9, 1), datetime.time(11, 0))]

结果:

A     2
B     6
C    10
Name: (2021-09-01, 11:00:00), dtype: int64

3。也可以使用.xs访问MultiIndex行索引,如下:

import datetime

df.xs(datetime.time(11,0), axis=0, level='Time')

结果:

            A  B   C
Date                
2021-09-01  2  6  10

4。如果您没有将 DateTime 索引拆分为多索引 Date & Time 的替代方法

其实如果你还没有将DatetimeIndex拆分成单独的日期时间索引,也可以使用.between_time()函数来过滤时间,如下:

df.between_time("11:00:00", "11:00:00")

如果您为 start_timeend_time 指定不同的值,您可以指定过滤的时间范围,而不仅仅是一个时间点。

结果:

                     A  B   C
DateTime                     
2021-09-01 11:00:00  2  6  10

如您所见,.between_time() 允许您以简单的字符串输入时间进行过滤,而不需要使用日期时间对象。这应该最接近您尝试过的使用df.loc["11:00:00"] 过滤的理想(但无效)语法。

作为建议,如果您只是为了按时间过滤而将 DatetimeIndex 拆分为单独的日期和时间索引,您可以考虑改用 .between_time() 函数。

【讨论】:

@Mahome 欢迎您!作为一个建议,如果只是为了按时间过滤,将 DatetimeIndex 拆分为单独的日期和时间索引,也可以考虑使用我上面提到的.between_time() 函数。 您已经涵盖了多种方式,真是太好了。非常感谢您的帮助。【参考方案2】:

我们可以用IndexSlice做正确的值切片

import datetime
out = df.loc[pd.IndexSlice[:,datetime.time(11, 0)],:]
Out[76]: 
                     A  B   C            DateTime
Date       Time                                  
2021-09-01 11:00:00  2  6  10 2021-09-01 11:00:00

【讨论】:

【参考方案3】:

为什么需要将日期时间分成两部分?

您可以使用indexer_at_time

>>> df
                     A  B   C
DateTime
2021-09-01 10:00:00  1  5   9
2021-09-01 11:00:00  2  6  10
2021-09-01 12:00:00  3  7  11
2021-09-01 13:00:00  4  8  12

# Extract 11:00:00 from any day
>>> df.iloc[df.index.indexer_at_time('11:00:00')]
                     A  B   C
DateTime
2021-09-01 11:00:00  2  6  10

您还可以创建代理以节省打字时间:

T = df.index.indexer_at_time
df.iloc[T('11:00:00')]

【讨论】:

以上是关于使用 .loc 函数错误的 Pandas DataFrame 时间索引的主要内容,如果未能解决你的问题,请参考以下文章

pandas根据列数据的值范围计数?

Pandas 错误:“DataFrame”对象没有属性“loc”

Pandas 错误:“DataFrame”对象没有属性“loc”

python pandas Data.Frame -- iloc和loc以及icol

Python pandas.DataFrame.loc函数方法的使用

在 Pandas 中使用 .loc 和 MultiIndex