【问题标题】:Pandas get row number of dataframe with composite indexPandas 获取具有复合索引的数据帧的行号
【发布时间】:2023-03-05 21:16:01
【问题描述】:

我有一个包含 .csv 文件的目录,其中包含 60 分钟的股票数据柱,以及一个 Python 脚本,用于将它们全部加载到 pandas 数据框中,并在符号和日期时间上编制索引,如下所示;

import pandas as pd
import glob
import numpy as np

allFiles = glob.glob("D:\\Data\\60 Min Bar Stocks\\*.csv")
frame = pd.DataFrame()
list_ = []
for file_ in allFiles:
    df = pd.read_csv(file_,index_col=None, header=0)
    list_.append(df)
frame = pd.concat(list_)

frame.set_index(['Symbol','Date'],inplace=True)

print(frame.loc["AAL", :])
print(frame.loc["AAL", :].loc["05-Jun-2017 09:00", :])

第一次打印带回以下内容;

                   Open   High    Low   Close   Volume
Date                                                  
05-Jun-2017 09:00  49.53  49.88  49.40  49.64   560155

05-Jun-2017 10:00  49.58  49.89  49.58  49.85   575165

第二次打印带回以下内容;

Open          49.53
High          49.88
Low           49.40
Close         49.64
Volume    560155.00
Name: 05-Jun-2017 09:00, dtype: float64

如何在数据框中找到该单独行的行索引,然后获得一个切片,该切片是由前一行、当前行和接下来的 10 行组成的 12 行?

【问题讨论】:

    标签: python pandas dataframe slice


    【解决方案1】:

    我认为您需要get_loc 来获取MultiIndex 的位置,然后通过iloc 选择:

    d = '05-Jun-2017 09:00'
    s = 'AAL'
    
    pos = df.index.get_loc((s,d))
    df1 = df.iloc[pos-1:pos + 11]
    print (df1)
    

    但如果t 是第一个值或10 最后一个值,则会出现问题:

    df1 = df.iloc[max(pos-1,0): min(pos+11,len(df.index))]
    

    示例:

    print (df)
                                Open    High     Low   Close  Volume
    Symbol Date                                                     
    AAL    05-Jun-2017 08:00  1.1801  1.1819  1.1801  1.1817       4
           05-Jun-2017 09:00  1.1817  1.1818  1.1804  1.1814      18
           05-Jun-2017 10:00  1.1817  1.1817  1.1802  1.1806      12
           05-Jun-2017 11:00  1.1807  1.1815  1.1795  1.1808      26
           05-Jun-2017 12:00  1.1803  1.1806  1.1790  1.1806       4
           05-Jun-2017 13:00  1.1801  1.1801  1.1779  1.1786      23
           05-Jun-2017 14:00  1.1795  1.1801  1.1776  1.1788      28
           05-Jun-2017 15:00  1.1793  1.1795  1.1782  1.1789      10
           05-Jun-2017 16:00  1.1780  1.1792  1.1776  1.1792      12
           05-Jun-2017 17:00  1.1788  1.1792  1.1788  1.1791       4
    

    d = '05-Jun-2017 09:00'
    s = 'AAL'
    
    pos = df.index.get_loc((s,d))
    df1 = df.iloc[max(pos-1,0): min(pos+10,len(df.index))]
    print (df1)
                                Open    High     Low   Close  Volume
    Symbol Date                                                     
    AAL    05-Jun-2017 08:00  1.1801  1.1819  1.1801  1.1817       4
           05-Jun-2017 09:00  1.1817  1.1818  1.1804  1.1814      18
           05-Jun-2017 10:00  1.1817  1.1817  1.1802  1.1806      12
           05-Jun-2017 11:00  1.1807  1.1815  1.1795  1.1808      26
           05-Jun-2017 12:00  1.1803  1.1806  1.1790  1.1806       4
           05-Jun-2017 13:00  1.1801  1.1801  1.1779  1.1786      23
           05-Jun-2017 14:00  1.1795  1.1801  1.1776  1.1788      28
           05-Jun-2017 15:00  1.1793  1.1795  1.1782  1.1789      10
           05-Jun-2017 16:00  1.1780  1.1792  1.1776  1.1792      12
           05-Jun-2017 17:00  1.1788  1.1792  1.1788  1.1791       4
    

    不可能选择上一行,因为时间戳t 是索引的第一个值:

    d = '05-Jun-2017 08:00'
    s = 'AAL'
    
    pos = df.index.get_loc((s,d))
    df1 = df.iloc[max(pos-1,0): min(pos+10,len(df.index))]
    print (df1)
                                Open    High     Low   Close  Volume
    Symbol Date                                                     
    AAL    05-Jun-2017 08:00  1.1801  1.1819  1.1801  1.1817       4
           05-Jun-2017 09:00  1.1817  1.1818  1.1804  1.1814      18
           05-Jun-2017 10:00  1.1817  1.1817  1.1802  1.1806      12
           05-Jun-2017 11:00  1.1807  1.1815  1.1795  1.1808      26
           05-Jun-2017 12:00  1.1803  1.1806  1.1790  1.1806       4
           05-Jun-2017 13:00  1.1801  1.1801  1.1779  1.1786      23
           05-Jun-2017 14:00  1.1795  1.1801  1.1776  1.1788      28
           05-Jun-2017 15:00  1.1793  1.1795  1.1782  1.1789      10
           05-Jun-2017 16:00  1.1780  1.1792  1.1776  1.1792      12
           05-Jun-2017 17:00  1.1788  1.1792  1.1788  1.1791       4
    

    不可能选择下一行的所有 10 个,因为 t 是后面的 3.rd 值:

    d = '05-Jun-2017 15:00'
    s = 'AAL'
    
    pos = df.index.get_loc((s,d))
    df1 = df.iloc[max(pos-1,0): min(pos+10,len(df.index))]
    print (df1)
                                Open    High     Low   Close  Volume
    Symbol Date                                                     
    AAL    05-Jun-2017 14:00  1.1795  1.1801  1.1776  1.1788      28
           05-Jun-2017 15:00  1.1793  1.1795  1.1782  1.1789      10
           05-Jun-2017 16:00  1.1780  1.1792  1.1776  1.1792      12
           05-Jun-2017 17:00  1.1788  1.1792  1.1788  1.1791       4
    

    【讨论】:

    • 谢谢!这是可行的,但有一个小问题,我认为这与数据框的整体排序顺序有关。文件中的最后一个符号是 ZION,“AAL”之后的符号是“AAPL”,所以当我使用您的解决方案时,我实际得到的是 2017 年 6 月 6 日 ZION 的最后一个条目,AAL 的 8 个条目2017 年 6 月 7 日,然后是 2017 年 6 月 7 日 AAPL 的前 3 个条目...我如何按符号然后按日期对其进行排序,以便此切片仅返回 AAL 的行?
    • 知道了!我添加了以下行,现在它可以工作了; frame.sort_index(inplace=True)
    猜你喜欢
    • 2015-02-10
    • 2018-05-18
    • 2017-02-06
    • 2020-08-03
    • 2021-05-16
    • 2016-07-31
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    相关资源
    最近更新 更多