代码之家  ›  专栏  ›  技术社区  ›  user7304253

如何自动将数据添加到历史股价中缺失的天数?

  •  0
  • user7304253  · 技术社区  · 7 年前

    我想写一个python脚本来检查是否有遗漏的一天。如果有,则应采用最近一天的价格,并在数据中创建新的一天。我的意思是如下所示。我的数据在CSV文件中。你知道怎么做吗?

    之前:

    MSFT,5-Jun-07,259.16
    MSFT,3-Jun-07,253.28
    MSFT,1-Jun-07,249.95
    MSFT,31-May-07,248.71
    MSFT,29-May-07,243.31
    

    之后:

    MSFT,5-Jun-07,259.16
    MSFT,4-Jun-07,253.28
    MSFT,3-Jun-07,253.28
    MSFT,2-Jun-07,249.95
    MSFT,1-Jun-07,249.95
    MSFT,31-May-07,248.71
    MSFT,30-May-07,243.31
    MSFT,29-May-07,243.31
    

    我的解决方案:

    import pandas as pd
    df = pd.read_csv("path/to/file/file.csv",names=list("abc")) # read string as file
    
    
    cols = df.columns # store column order
    df.b = pd.to_datetime(df.b) # convert col Date to datetime
    df.set_index("b",inplace=True) # set col Date as index
    df = df.resample("D").ffill().reset_index() # resample Days and fill values
    
    df = df[cols] # revert order
    df.sort_values(by="b",ascending=False,inplace=True) # sort by date
    df["b"] = df["b"].dt.strftime("%-d-%b-%y") # revert date format
    df.to_csv("data.csv",index=False,header=False) #specify outputfile if needed
    
    print(df.to_string())
    
    3 回复  |  直到 7 年前
        1
  •  1
  •   Anton vBR    7 年前

    使用 熊猫 库此操作可以在单行上进行。但首先,我们需要以正确的格式读入数据:

    import io
    import pandas as pd
    
    s = u"""name,Date,Close
    MSFT,30-Dec-16,771.82
    MSFT,29-Dec-16,782.79
    MSFT,28-Dec-16,785.05
    MSFT,27-Dec-16,791.55
    MSFT,23-Dec-16,789.91
    MSFT,16-Dec-16,790.8
    MSFT,15-Dec-16,797.85
    MSFT,14-Dec-16,797.07"""
    
    #df = pd.read_csv("path/to/file.csv") # read from file
    df = pd.read_csv(io.StringIO(s)) # read string as file
    
    cols = df.columns # store column order
    df.Date = pd.to_datetime(df.Date) # convert col Date to datetime
    df.set_index("Date",inplace=True) # set col Date as index
    df = df.resample("D").ffill().reset_index() # resample Days and fill values
    
    df
    

    返回:

             Date  name   Close
    0  2016-12-14  MSFT  797.07
    1  2016-12-15  MSFT  797.85
    2  2016-12-16  MSFT  790.80
    3  2016-12-17  MSFT  790.80
    4  2016-12-18  MSFT  790.80
    5  2016-12-19  MSFT  790.80
    6  2016-12-20  MSFT  790.80
    7  2016-12-21  MSFT  790.80
    8  2016-12-22  MSFT  790.80
    9  2016-12-23  MSFT  789.91
    10 2016-12-24  MSFT  789.91
    11 2016-12-25  MSFT  789.91
    12 2016-12-26  MSFT  789.91
    13 2016-12-27  MSFT  791.55
    14 2016-12-28  MSFT  785.05
    15 2016-12-29  MSFT  782.79
    16 2016-12-30  MSFT  771.82
    

    返回到csv:

    df = df[cols] # revert order
    df.sort_values(by="Date",ascending=False,inplace=True) # sort by date
    df["Date"] = df["Date"].dt.strftime("%-d-%b-%y") # revert date format
    df.to_csv(index=False,header=False) #specify outputfile if needed
    

    输出:

    MSFT,30-Dec-16,771.82
    MSFT,29-Dec-16,782.79
    MSFT,28-Dec-16,785.05
    MSFT,27-Dec-16,791.55
    MSFT,26-Dec-16,789.91
    MSFT,25-Dec-16,789.91
    MSFT,24-Dec-16,789.91
    MSFT,23-Dec-16,789.91
    ...
    
        2
  •  0
  •   jaguar    7 年前

    为此,需要使用嵌套for循环遍历数据帧。这看起来像:

    for column in df:
        for row in df:
            do_something()
    

    do_something()
    

    部分代码可能类似于检查日期之间是否有差距。然后,您可以从上面的行中复制其他列,并使用以下命令插入新行:

    df.loc[row] = [2, 3, 4]  # adding a row
    df.index = df.index + 1  # shifting index
    df = df.sort()  # sorting by index 
    

    希望这能帮助你了解如何解决这个问题。如果你想要更多的代码,请告诉我!

        3
  •  0
  •   Bill Bell    7 年前

    此代码使用标准例程。

    from datetime import datetime, timedelta
    

    def glean(s):
        msft, date_part, amount = s.split(',')
        if date_part.find('-')==1: 
            date_part = '0'+date_part
        date = datetime.strptime(date_part, '%d-%b-%y')
        return date, amount
    

    同样,日期必须格式化,以便在主代码的多个位置与其他数据块一起输出。

    def out(date,amount):
        date_str = date.strftime('%d-%b-%y')
        print(('%s,%s,%s' % ('MSFT', date_str, amount)).replace('MSFT,0', 'MSFT,'))
    
    with open('before.txt') as before:
    

    我自己阅读了第一行数据,以确定第一个日期,并与下一行中的日期进行比较。

    previous_date, previous_amount = glean(before.readline().strip())
    out(previous_date, previous_amount)
    for line in before.readlines():
        date, amount = glean(line.strip())
    

    我计算当前行和前一行之间经过的时间,以了解要输出多少行来代替缺失的行。

        elapsed = previous_date - date
    

    setting_date previous_date 对于没有数据的天数。如果有,每天省略一行。

        setting_date = previous_date
        for i in range(-1+elapsed.days):
            setting_date -= timedelta(days=1)
            out(setting_date, previous_amount)
    

    现在输出可用的数据行。

        out(date, amount)
    

    现在 上一个_日期 previous_amount

        previous_date, previous_amount = date, amount 
    

    输出:

    MSFT,5-Jun-07,259.16
    MSFT,4-Jun-07,259.16
    MSFT,3-Jun-07,253.28
    MSFT,2-Jun-07,253.28
    MSFT,1-Jun-07,249.95
    MSFT,31-May-07,248.71
    MSFT,30-May-07,248.71
    MSFT,29-May-07,243.31