2012-12-28 73 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 –