【问题标题】:Pandas series looping with specific index level具有特定索引级别的 Pandas 系列循环
【发布时间】:2019-02-04 14:07:38
【问题描述】:

我有一个带有多个索引的 Pandas 系列,我正在尝试按级别“ID”进行迭代。这个想法是 for 循环将递增到下一个“ID”,因此我可以将与该 ID 关联的所有值切片以传递给一个函数,以将每个 ID 绘制为不同的颜色。

                rest        confidence
ID  ts      
33  21:30:50    150.01001   95.9864
    21:30:52    148.826187  79.530624
    21:30:53    148.957123  54.75795
55  21:30:52    168.325577  37.43358
    21:30:53    172.813446  33.133442
61  21:30:50    107.335625  32.807873

Pandas 文档(Pandas MultiIndex) 有助于切片和获得工作 for 循环(如下)。使用 df.index.levels[0] 返回我需要运行 for 循环的索引值,但是,似乎就像有一种更好更快的方法来告诉它迭代给定的索引级别。有吗?

for IDn in list(df.index.levels[0]):
    print( df.loc[ (IDn,slice(None)),['confidence','rest'] ].xs(slice(None),level='ID') )

我已经解决了这个问题(Pandas how to loop through a MultiIndex series),似乎 groupby 和 apply 函数就是这样。

【问题讨论】:

    标签: python pandas indexing series


    【解决方案1】:

    您可以使用groupby() 并循环访问各个组。首先重新创建您的数据框:

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    
    index = pd.MultiIndex.from_product([[33, 55, 61],['21:30:50','21:30:52','21:30:53']], names=['ID','ts'])
    
    df = pd.DataFrame([[150.01001,   95.9864],
                    [148.826187,  79.530624],
                    [148.957123,  54.75795],
                    [np.nan, np.nan],
                    [168.325577,  37.43358],
                    [172.813446,  33.133442],
                    [107.335625,  32.807873],
                    [np.nan, np.nan],
                    [np.nan, np.nan]],
                    columns=['rest', 'confidence'], index=index).dropna()
    

    产量:

                       rest  confidence
    ID ts                              
    33 21:30:50  150.010010   95.986400
       21:30:52  148.826187   79.530624
       21:30:53  148.957123   54.757950
    55 21:30:52  168.325577   37.433580
       21:30:53  172.813446   33.133442
    61 21:30:50  107.335625   32.807873
    

    然后使用groupby('ID'):

    grouped = df.groupby('ID')
    
    fig, ax = plt.subplots()
    for name, group in grouped:
        ax.plot(group['rest'], group['confidence'], marker='o', linestyle='', label=name)
    ax.legend()
    
    plt.xlabel('rest'); plt.ylabel('confidence')
    plt.title('Rest vs Confidence'); plt.grid(True)
    
    plt.show()
    

    生成以下散点图:

    更新

    为两个参数与时间的关系创建两个子图 (ts):

    df = df.reset_index()
    
    df['ts'] = pd.to_datetime(df['ts'])
    
    grouped = df.groupby('ID')
    
    fig, (ax1, ax2) = plt.subplots(1, 2)
    for name, group in grouped:
        ax1.plot(group['ts'], group['rest'], marker='o', linestyle='', label=name)
        ax2.plot(group['ts'], group['confidence'], marker='o', linestyle='', label=name)
    
    ax1.legend()
    ax1.set_xlabel('ts'); ax1.set_ylabel('rest')
    ax1.set_title('Rest vs ts'); ax1.grid(True)
    
    ax2.legend()
    ax2.set_xlabel('ts'); ax2.set_ylabel('confidence')
    ax2.set_title('Confidence vs ts'); ax2.grid(True)
    
    plt.show()
    

    这给出了以下内容:

    【讨论】:

    • 谢谢,我的目标是将“休息”和“信心”绘制为时间的函数。那可能吗?在尝试了您的示例后,我意识到时间索引已经消失了。我开始意识到将数据保留为没有多索引的普通数据框更容易,在它们各自的列中都有“ts”和“ID”。这样我可以在绘图时根据需要使用您的 groupby 示例。
    • 谢谢,我缺少的魔法线是“df = df.reset_index()”。在我尝试在执行 groupby 之前复制时间戳列之前。即使我给了它一个不同的名称,Groupby 也会破坏重复的时间戳列。我猜它看到了重复的数据并愉快地修复了它。
    猜你喜欢
    • 2020-05-19
    • 2019-11-19
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 2014-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多