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

Python 如何将数据自动添加到历史股价中缺失的天数?,python,pandas,parsing,finance,Python,Pandas,Parsing,Finance,我想写一个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-Ju

我想写一个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())

为此,您需要使用嵌套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 

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

此代码使用标准例程

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
    for i in range(-1+elapsed.days):
        setting_date -= timedelta(days=1)
        out(setting_date, previous_amount)
现在输出可用的数据行

    out(date, 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
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
...
使用pandas library,可以在单行上执行此操作。但首先,我们需要以正确的格式读入数据:

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,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
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
...

我收到一个错误-ValueError:时间数据“Date”与格式“%d-%b-%y”不匹配可能从csv文件加载数据会更容易,因为此时我的数据位于csv文件中。我将源代码添加到更新的问题中。有什么不对劲的建议吗?您可以按原样使用csv文件,只要它们符合问题中指定的格式。如果他们不这样做,所有的赌注都将失败!在使用datetime格式时,我稍微偏离了规则。规则没有抓住我,但他们抓住了你。我在编辑中添加了几行代码来处理这个问题。我还改变了输出,这实际上是正确的。我在回答中输入了一个不正确的早期版本。这可以通过csv模块完成,但这并不容易,可能更难理解。我仍然得到ValueError:时间数据“Date”与格式“%d-%b-%y”不匹配。我的解决方案有更新问题,谢谢您的帮助。我的csv文件中有数据。是否有任何简单的方法可以将此解决方案转换为从csv获取数据?是的,我尝试过,但得到了raise VALUERRORN string format VALUERROR:未知字符串format@JohnSmith我能够从字符串中读取数据。更新的代码我不太确定你的问题发生在哪里。我的解决方案是更新的问题,谢谢你的帮助。