2017-10-22 67 views
0

我想寫一個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()) 

回答

2

使用熊貓庫此操作可在一個單一的線路進行說明。但首先,我們需要在數據讀取到正確的格式:

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 
... 
+0

我有csv文件中的數據。有沒有簡單的方法來轉換此解決方案從csv獲取數據? – wahtdbogh

+0

是的,我試過了,但我得到了'提高ValueError(「未知字符串格式」) ValueError:未知字符串格式' – wahtdbogh

+0

我添加了示例CSV文件到更新的問題。 – wahtdbogh

0

要做到這一點,你需要使用嵌套的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 

希望這有助於給你,你會如何解決這個問題的想法。讓我知道你是否想要更多的代碼!

0

此代碼使用標準例程。

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_dateprevious_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_dateprevious_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 
+0

我收到一個錯誤 - 'ValueError:時間數據'日期'不匹配格式' %d-%b-%y''也許從csv文件加載數據會更容易一些,因爲此刻我在csv文件中有我的數據。我將我的源代碼添加到更新後的問題中。任何建議可能是錯誤的? – wahtdbogh

+0

您可以使用您的csv文件,因爲它們符合您問題中指出的格式。 (如果不是,所有投注都關閉!)我在使用該日期時間格式時略微避開了規則。規則沒有吸引我,但他們抓住了你。我在編輯中添加了幾行'glean'來處理這個問題。我也改變了實際上正確的輸出。我在回答中提出了一個較早的(不正確的)版本。 –

+0

這可以用csv模塊完成,但它不會更容易,可能會稍微難一些。 –

相關問題