【问题标题】:Multi-indexing - accessing the last time in every day多索引 - 访问每天的最后一次
【发布时间】:2016-11-25 14:26:58
【问题描述】:

Pandas 中的多索引新功能。我有这样的数据

Date        Time      value
2014-01-14  12:00:04   .424
            12:01:12   .342
            12:01:19   .341
            ...
            12:05:49   .23
2014-05-12  ...
            1:02:42    .23
....

现在,我想访问每个日期的最后时间并将值存储在某个数组中。我做了一个这样的多索引

df= pd.read_csv("df.csv",index_col=0)
df.index = pd.to_datetime(df.index,infer_datetime_format=True)
df.index =        pd.MultiIndex.from_arrays([df.index.date,df.index.time],names=['Date','Time'])

df= df[~df.index.duplicated(keep='first')]
dates = df.index.get_level_values(0)

所以我将日期保存为数组。我想遍历日期,但无法正确获取语法或访问值不正确。我尝试了一个 for 循环,但无法让它运行(for date in dates),也无法直接访问(df.loc[dates[i]] 或类似的东西)。每个日期中时间变量的数量也各不相同。有没有办法解决这个问题?

【问题讨论】:

    标签: python datetime pandas indexing


    【解决方案1】:

    这听起来像是groupby/max 操作。更具体地说,您希望按Date 分组并通过采用max 聚合Times。由于聚合只能在 column 值上完成,我们需要将 Time 索引级别更改为列(通过使用 reset_index):

    import pandas as pd
    
    df = pd.DataFrame({'Date': ['2014-01-14', '2014-01-14', '2014-01-14', '2014-01-14', '2014-05-12', '2014-05-12'], 'Time': ['12:00:04', '12:01:12', '12:01:19', '12:05:49', '01:01:59', '01:02:42'], 'value': [0.42399999999999999, 0.34200000000000003, 0.34100000000000003, 0.23000000000000001, 0.0, 0.23000000000000001]})
    df['Date'] = pd.to_datetime(df['Date'])
    df = df.set_index(['Date', 'Time'])
    
    df = df.reset_index('Time', drop=False)
    max_times = df.groupby(level=0)['Time'].max()
    print(max_times)
    

    产量

    Date
    2014-01-14    12:05:49
    2014-05-12     1:02:42
    Name: Time, dtype: object
    

    如果您希望选择整行,则可以使用idxmax——但有一点需要注意。 idxmax 返回索引标签。因此,索引必须是唯一,标签才能表示唯一的行。由于Date 级别本身并不是唯一的,要使用idxmax,我们需要完全使用reset_index(以创建唯一整数的索引):

    df = pd.DataFrame({'Date': ['2014-01-14', '2014-01-14', '2014-01-14', '2014-01-14', '2014-05-12', '2014-05-12'], 'Time': ['12:00:04', '12:01:12', '12:01:19', '12:05:49', '01:01:59', '1:02:42'], 'value': [0.42399999999999999, 0.34200000000000003, 0.34100000000000003, 0.23000000000000001, 0.0, 0.23000000000000001]})
    df['Date'] = pd.to_datetime(df['Date'])
    df['Time'] = pd.to_timedelta(df['Time'])
    df = df.set_index(['Date', 'Time'])
    
    df = df.reset_index()
    idx = df.groupby(['Date'])['Time'].idxmax()
    print(df.loc[idx])
    

    产量

            Date     Time  value
    3 2014-01-14 12:05:49   0.23
    5 2014-05-12 01:02:42   0.23
    

    在保留 MultiIndex 的同时,我没有看到这样做的好方法。 在设置 MultiIndex 之前执行groupby 操作更容易。 此外,最好将日期时间保留为一个值,而不是将其分成两部分。请注意,给定一个类似日期时间/周期的系列,.dt accessor 使您可以根据需要轻松访问datetime。因此,您可以按Date 分组,而无需创建Date 列:

    df = pd.DataFrame({'DateTime': ['2014-01-14 12:00:04', '2014-01-14 12:01:12', '2014-01-14 12:01:19', '2014-01-14 12:05:49', '2014-05-12 01:01:59', '2014-05-12 01:02:42'], 'value': [0.42399999999999999, 0.34200000000000003, 0.34100000000000003, 0.23000000000000001, 0.0, 0.23000000000000001]})
    df['DateTime'] = pd.to_datetime(df['DateTime'])
    # df = pd.read_csv('df.csv', parse_dates=[0])
    
    idx = df.groupby(df['DateTime'].dt.date)['DateTime'].idxmax()
    result = df.loc[idx]
    print(result)
    

    产量

                 DateTime  value
    3 2014-01-14 12:05:49   0.23
    5 2014-05-12 01:02:42   0.23
    

    【讨论】:

    • 保持完整的日期时间在一起必须是要走的路。 +1
    • 经过大量调整后,我终于找到了一个我非常喜欢的解决方案……然后我再次查看了你的解决方案,它几乎是一样的。 :-)
    • 是的,多索引是错误的做法。我认为如果我可以立即访问索引(我没有)会很有用,但这最终会好很多。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-04-19
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    相关资源
    最近更新 更多