2012-12-28 102 views
2

我有一個csv文件,日期,時間,價格,mag,信號。 62035行;每天有42次與文件中的每個唯一日期相關聯。列表理解循環

對於每個日期,當信號列中出現'S'時,在'S'出現時附加相應的價格。以下是嘗試。

from pandas import * 
from numpy import * 
from io import * 
from os import * 
from sys import * 

DF1 = read_csv('___.csv') 
idf=DF1.set_index(['date','time','price'],inplace=True) 
sStore=[] 
for i in idf.index[i][0]: 
    sStore.append([idf.index[j][2] for j in idf[j][1] if idf['signal']=='S']) 
sStore.head()  
Traceback (most recent call last) 
<ipython-input-7-8769220929e4> in <module>() 
    1 sStore=[] 
    2 
----> 3 for time in idf.index[i][0]: 
    4 
    5  sStore.append([idf.index[j][2] for j in idf[j][1] if idf['signal']=='S']) 

NameError: name 'i' is not defined 

我不明白爲什麼我的索引不在這裏不允許的。謝謝。

我也認爲這是奇怪的是:

idf.index.levels [0]將顯示日期「不解析」,因爲它是在該文件中,但出故障了。儘管parse_date = True作爲set_index中的參數。

我提起這事,因爲我想邊的刷卡問題是這樣的:基於以下DSM的評論

for i in idf.index.levels[0]: 

    sStore.append([idf.index[j][2] for j in idf.index.levels[1] if idf['signal']=='S']) 

sStore.head() 

我的編輯2012年12月30日:

我想用我的想法得到P,如下面我評論的。其中,如果S = B,對於任何給定的日期,我們利用收盤時間差,1620

v=[df["signal"]=="S"] 
t=[df["time"]=="1620"] 
u=[df["signal"]!="S"] 

df["price"][[v and (u and t)]] 

也就是說,「給我的價格在1620(即使它不給!」賣信號「,S),以便我可以用」額外的B「來區分 - 對於B> S的特殊情況,這忽略了對稱關係(其中S> B),但現在我想理解這個邏輯問題。

在回溯,這個表達式給出:

ValueError: boolean index array should have 1 dimension 

注意,以便調用DF [「時間」] 我做ñ ot set_index here。嘗試聯合運算符|得出:

TypeError: unsupported operand type(s) for |: 'list' and 'list' 

在最大院士的做法

@Max研究員

點是在一天結束的時候,收出位置尋找;所以我們需要在最後收集所有那些已經累積的B,S的「卸貨」價格;但並沒有互相排斥。 如果我說:

filterFunc1 = lambda row: row["signal"] == "S" and ([row["signal"] != "S"][row["price"]=="1620"]) 
filterFunc2 =lambda row: ([row["price"]=="1620"][row["signal"] != "S"]) 

filterFunc=filterFunc1 and filterFunc2 

filteredData = itertools.ifilter(filterFunc, reader) 

在回溯:

IndexError: list index out of range 
+3

變量'i'在您的迭代過程中創建('for i'),但您正在使用'我'確定迭代對象('idf.index [i] [0]')。由於'idf.index [i] [0]'部分將首先被評估,並且由於此時沒有'i'的值,所以將會拋出錯誤。 – RocketDonkey

+0

@phihag如果我想「做算法」限制在那些日子的42次,所有的日子裏。我該如何解決這個問題?你看到上面列表理解的其他問題嗎?謝謝。 –

+3

不相關,但你真的**不想做所有'''' - 進口。 ''從numpy導入*'將用'numpy'替代內建'any',它不處理genexps,所以'any((對於我在範圍(3)中爲False)} == True'; 'from os import *'將用'os.open'替換'open',所以大部分'open'調用都會返回'TypeError:需要一個整數';等等。 – DSM

回答

2

使用@Max Fellows方便的示例數據,我們可以在pandas中查看它。 [順便說一句,你應該總是嘗試提供一個簡短的,自包含的,正確的例子(更多細節見here),以便那些試圖幫助你的人不必花時間想出一個。]

首先,import pandas as pd。然後:

In [23]: df = pd.read_csv("sample.csv", names="date time price mag signal".split()) 

In [24]: df.set_index(["date", "time"], inplace=True) 

這給了我

In [25]: df 
Out[25]: 
       price  mag signal 
date  time      
12/28/2012 1:30  10  foo  S 
      2:15  11  bar  N 
      3:00  12  baz  S 
      4:45  13 fibble  N 
      5:30  14 whatsit  S 
      6:15  15  bobs  N 
      7:00  16 widgets  S 
      7:45  17 weevils  N 
      8:30  18 badger  S 
      9:15  19 moose  S 
11/29/2012 1:30  10  foo  N 
      2:15  11  bar  N 
      3:00  12  baz  S 
      4:45  13 fibble  N 
      5:30  14 whatsit  N 
      6:15  15  bobs  N 
      7:00  16 widgets  S 
      7:45  17 weevils  N 
      8:30  18 badger  N 
      9:15  19 moose  N 
[etc.] 

我們可以看到這行有S信號容易:

In [26]: df["signal"] == "S" 
Out[26]: 
date  time 
12/28/2012 1:30  True 
      2:15 False 
      3:00  True 
      4:45 False 
      5:30  True 
      6:15 False 
[etc..] 

,我們可以也使用這個選擇:

In [27]: df["price"][df["signal"] == "S"] 
Out[27]: 
date  time 
12/28/2012 1:30 10 
      3:00 12 
      5:30 14 
      7:00 16 
      8:30 18 
      9:15 19 
11/29/2012 3:00 12 
      7:00 16 
12/29/2012 3:00 12 
      7:00 16 
8/9/2008 3:00 12 
      7:00 16 
Name: price 

這是一個DataFrame與每個日期,時間和價格有S。如果你只是想一個列表:

In [28]: list(df["price"][df["signal"] == "S"]) 
Out[28]: [10.0, 12.0, 14.0, 16.0, 18.0, 19.0, 12.0, 16.0, 12.0, 16.0, 12.0, 16.0] 

更新

v=[df["signal"]=="S"]使得v一個Python list包含Series。這不是你想要的。 df["price"][[v and (u and t)]]對我來說沒什麼意義 - :vu是互斥的,所以如果你和他們在一起,你什麼都得不到。對於這些邏輯向量操作,可以使用&|而不是andor。再次使用參考數據:

In [85]: import pandas as pd 

In [86]: df = pd.read_csv("sample.csv", names="date time price mag signal".split()) 

In [87]: v=df["signal"]=="S" 

In [88]: t=df["time"]=="4:45" 

In [89]: u=df["signal"]!="S" 

In [90]: df[t] 
Out[90]: 
      date time price  mag signal 
3 12/28/2012 4:45  13 fibble  N 
13 11/29/2012 4:45  13 fibble  N 
23 12/29/2012 4:45  13 fibble  N 
33 8/9/2008 4:45  13 fibble  N 

In [91]: df["price"][t] 
Out[91]: 
3  13 
13 13 
23 13 
33 13 
Name: price 

In [92]: df["price"][v | (u & t)] 
Out[92]: 
0  10 
2  12 
3  13 
4  14 
6  16 
8  18 
9  19 
12 12 
13 13 
16 16 
22 12 
23 13 
26 16 
32 12 
33 13 
36 16 
Name: price 

[注意:這個問題現在變得太長和曲折。我建議花一些時間通過控制檯上的pandas文檔中的示例來了解它。]

+0

+1使用OP的原始庫,這是更聰明:) –

+0

@MaxFellows&DSM:謝謝你們倆!我希望通過兩種方式來實踐。你介意看看上面的編輯? –

1

這是因爲i還沒有定義,就像錯誤消息指出。

在這一行:

for i in idf.index[i][0]: 

你告訴Python解釋器在迭代通過列表從表達idf.index[i][0]返回產生的所有值,但你還沒有定義什麼i是(雖然你正試圖以將列表中的每個項目也設置爲變量i)。

Python for ... in ...循環的工作方式是它採用最右邊的組件並要求迭代器中的next項。然後它將通過調用產生的值分配給左側提供的變量名稱。

2

嘗試這樣:

for i in range(len(idf.index)): 
    value = idf.index[i][0] 

用於與j指數變量迭代同樣的事情。正如已經指出的那樣,你不能在被迭代的表達式中引用迭代索引,除此之外,你需要執行一個非常特定的迭代(遍歷矩陣中的一列),而Python的默認迭代器不會工作。的框中「,因此這裏需要自定義索引處理。

2

這就是我認爲你要根據你的編輯來完成的事情:對於CSV文件中的每個日期,將日期和每個項目的價格清單一起用信號「S」分組。

你沒有包括在你的問題的任何樣本數據,所以我做了一個測試一個,我希望你描述的格式相匹配:

12/28/2012,1:30,10.00,"foo","S" 
12/28/2012,2:15,11.00,"bar","N" 
12/28/2012,3:00,12.00,"baz","S" 
12/28/2012,4:45,13.00,"fibble","N" 
12/28/2012,5:30,14.00,"whatsit","S" 
12/28/2012,6:15,15.00,"bobs","N" 
12/28/2012,7:00,16.00,"widgets","S" 
12/28/2012,7:45,17.00,"weevils","N" 
12/28/2012,8:30,18.00,"badger","S" 
12/28/2012,9:15,19.00,"moose","S" 
11/29/2012,1:30,10.00,"foo","N" 
11/29/2012,2:15,11.00,"bar","N" 
11/29/2012,3:00,12.00,"baz","S" 
11/29/2012,4:45,13.00,"fibble","N" 
11/29/2012,5:30,14.00,"whatsit","N" 
11/29/2012,6:15,15.00,"bobs","N" 
11/29/2012,7:00,16.00,"widgets","S" 
11/29/2012,7:45,17.00,"weevils","N" 
11/29/2012,8:30,18.00,"badger","N" 
11/29/2012,9:15,19.00,"moose","N" 
12/29/2012,1:30,10.00,"foo","N" 
12/29/2012,2:15,11.00,"bar","N" 
12/29/2012,3:00,12.00,"baz","S" 
12/29/2012,4:45,13.00,"fibble","N" 
12/29/2012,5:30,14.00,"whatsit","N" 
12/29/2012,6:15,15.00,"bobs","N" 
12/29/2012,7:00,16.00,"widgets","S" 
12/29/2012,7:45,17.00,"weevils","N" 
12/29/2012,8:30,18.00,"badger","N" 
12/29/2012,9:15,19.00,"moose","N" 
8/9/2008,1:30,10.00,"foo","N" 
8/9/2008,2:15,11.00,"bar","N" 
8/9/2008,3:00,12.00,"baz","S" 
8/9/2008,4:45,13.00,"fibble","N" 
8/9/2008,5:30,14.00,"whatsit","N" 
8/9/2008,6:15,15.00,"bobs","N" 
8/9/2008,7:00,16.00,"widgets","S" 
8/9/2008,7:45,17.00,"weevils","N" 
8/9/2008,8:30,18.00,"badger","N" 
8/9/2008,9:15,19.00,"moose","N" 

下面是使用Python 2.7的方法和內置庫到組它的方式,它聽起來就像你想要的:

import csv 
import itertools 
import time 
from collections import OrderedDict 

with open("sample.csv", "r") as file: 
    reader = csv.DictReader(file, 
          fieldnames=["date", "time", "price", "mag", "signal"]) 

    # Reduce the size of the data set by filtering out the non-"S" rows. 
    filterFunc = lambda row: row["signal"] == "S" 
    filteredData = itertools.ifilter(filterFunc, reader) 

    # Sort by date so we can use the groupby function. 
    dateKeyFunc = lambda row: time.strptime(row["date"], r"%m/%d/%Y") 
    sortedData = sorted(filteredData, key=dateKeyFunc) 

    # Group by date: create a new dictionary of date to a list of prices. 
    datePrices = OrderedDict((date, [row["price"] for row in rows]) 
          for date, rows 
          in itertools.groupby(sortedData, dateKeyFunc)) 

for date, prices in datePrices.iteritems(): 
    print "{0}: {1}".format(time.strftime(r"%m/%d/%Y", date), 
          ", ".join(str(price) for price in prices)) 

>>> 08/09/2008: 12.00, 16.00 
>>> 11/29/2012: 12.00, 16.00 
>>> 12/28/2012: 10.00, 12.00, 14.00, 16.00, 18.00, 19.00 
>>> 12/29/2012: 12.00, 16.00 

的類型轉換是你的,因爲你可能會使用其他庫做你的CSV閱讀,但會告訴你如何開始 - 和請注意@ DSM關於導入*的評論。

+0

我跑你的例子;它提供了所有的'S'價格以及特殊順序的日期:3/4/2009,3/4/2008,1/14/2009,1/14/2008,5/1/2012,3/5/2008,3/10/2009年,...等等。 你會評論爲什麼日期的順序是這樣嗎?我問,因爲這對於我真正需要做的事很重要:寫一個P&L函數,計算每天在給定日期的所有i的總和(S_i-B_i)。並返回文件中所有日期的P&L號碼。 (在num('B')!= num('S')的情況下,我想考慮從收盤價中減去(這裏是1620) –

+0

你在哪裏定義'行'你在哪裏調用'rows'來構造datePrices?非常感謝 –

+1

編輯我對包含日期轉換的響應 - 奇怪的順序是因爲我最初遺漏了類型轉換,所以它按字符串順序排序(然後字典儘管在評論中額外的細節之後,有更好的方法來實現您的最終目標;您可以考慮將CSV文件加載到數據庫中並查詢它,請參閱http://docs.python。 org/2/library/time.html –