有什么方法可以提高效率?

时间:2020-02-06 16:08:38

标签: python-3.x

我还有24次尝试提交此任务的尝试。我花了几个小时,我的大脑不再工作了。我是Python的初学者,可否请您找出问题所在?如果可能,我希望看到正确的代码。 这是任务本身以及我在下面编写的代码。

请注意,您可以访问您语言的所有标准模块/软件包/库。但是无法访问其他库(python中的numpy,c ++中的boost等)。

系统会为您提供CSV文件的内容,其中包含有关交易集的信息。它包含以下列:

TIME-格式的交易时间戳记Hour:Minute:Second.Millisecond 价格-每股价格 SIZE-此交易中执行的股票数量 交易所-执行此交易的交易所 对于每个交易所,找到一个一分钟的窗口,在此期间,该交易所进行的交易最多。

请注意:

您需要发送程序的源代码。 您只有25次尝试提交此任务的解决方案。 您可以访问您语言的所有标准模块/软件包/库。但是无法访问其他库(python中的numpy,c ++中的boost等)。 输入格式 输入包含几行。您可以从标准输入或文件“ trades.csv”中读取它

每一行都包含有关一项交易的信息:时间,价格,大小和交换。数字用逗号分隔。

行以时间戳的升序列出。多行可以包含相同的时间戳。

输入文件的大小不超过5 MB。

请参见下面的示例以了解确切的输入格式。

输出格式 如果输入包含有关k个交换的信息,则将k行打印到标准输出中。

每行都应包含唯一的数字-一分钟窗口内的最大交易数。

您应该按名字的字典顺序打印答案。

样本 输入输出 09:30:01.034,36.99,100,V 09:30:55.000,37.08,205,V 09:30:55.554,36.90,54,V 09:30:55.556,36.91,99,D 09:31:01.033,36.94,100,D 09:31:01.034,36.95,900,V 2 3 笔记 在示例中,在交易所“ V”上执行了四笔交易,在交易所“ D”上执行了两笔交易。并非所有的“ V”交易都适合在一分钟的窗口中,因此“ V”的答案是三个。

  X = []
    with open('trades.csv', 'r') as tr:
      for line in tr:
        line = line.strip('\xef\xbb\xbf\r\n ')
        X.append(line.split(','))

    dex = {}

    for item in X:
      dex[item[3]] = []
    for item in X:
      dex[item[3]].append(float(item[0][:2])*60.+float(item[0][3:5])+float(item[0][6:8])/60.+float(item[0][9:])/60000.)
    for item in dex:
      count = 1
      ccount = 1
      if dex[item][len(dex[item])-1]-dex[item][0] <1: 
        count = len(dex[item]) 
      else:
        for t in range(len(dex[item])-1):
          for tt in range(len(dex[item])-t-1):
            if dex[item][tt+t+1]-dex[item][t] <1:
              ccount += 1
            else: break
          if ccount>count: 
            count=ccount
          ccount=1
      print(count)

2 个答案:

答案 0 :(得分:1)

首先,对于这种简单情况(例如在Ed-Ward的示例中),不必使用 datetime csv 模块。

  • 如果我们从时间字符串中删除冒号和点号,则可以将其直接转换为int()-比您在示例中尝试的方法更简单。
  • 未使用方言和特殊格式等CSV功能,因此我建议使用简单的split(“,”)

现在要提高效率。效率意味着time complexity。 从头到尾遍历数组的次数越多,算法就越复杂。

因此,我们的目标是最大程度地减少周期数,最好在所有行中只遍历一次,尤其要避免嵌套循环和从头到尾遍历集合。 对于此类任务,最好使用deque而不是元组或列表,因为您可以pop()第一个元素,并在最后一个元素后附加complexity of O(1)

只需将每个时间追加所需的交换到交换队列的末尾,直到 current first 元素之间的差异超过1分钟。然后只需使用popleft()删除第一个元素,然后继续比较即可。完成整个文件后-每个队列的长度将是最大1分钟窗口。

具有线性时间复杂度O(n)的示例:

from collections import deque

ex_list = {}

s = open("trades.csv").read().replace(":", "").replace(".", "")
for line in s.splitlines():
    s = line.split(",")
    curr_tm = int(s[0])
    curr_ex = s[3]

    if curr_ex not in ex_list:
        ex_list[curr_ex] = deque()
    
    ex_list[curr_ex].append(curr_tm)

    if curr_tm >= ex_list[curr_ex][0] + 100000:
        ex_list[curr_ex].popleft()

print("\n".join([str(len(ex_list[k])) for k in sorted(ex_list.keys())]))

答案 1 :(得分:0)

此代码应正常工作:

import csv
import datetime

diff = datetime.timedelta(minutes=1)
def date_calc(start, dates):
    for i, date in enumerate(dates):
        if date >= start + diff:
            return i
    return i + 1

exchanges = {}
with open("trades.csv") as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        this_exchange = row[3]
        if this_exchange not in exchanges:
            exchanges[this_exchange] = []

        time = datetime.datetime.strptime(row[0], "%H:%M:%S.%f")
        exchanges[this_exchange].append(time)

ex_max = {}
for name, dates in exchanges.items():
    ex_max[name] = 0
    for i, d in enumerate(dates):
        x = date_calc(d, dates[i:])
        if x > ex_max[name]:
            ex_max[name] = x

print('\n'.join([str(ex_max[k]) for k in sorted(ex_max.keys())]))

输出:

2
3

(显然,请在上传之前亲自检查一下:))

我认为您当前代码的问题在于您没有将输出放在lexicographical order of their names ...

如果您想使用当前代码,那么这里是一个(希望的)固定版本:

X = []
with open('trades.csv', 'r') as tr:
  for line in tr:
    line = line.strip('\xef\xbb\xbf\r\n ')
    X.append(line.split(','))

dex = {}
counts = []

for item in X:
  dex[item[3]] = []
for item in X:
  dex[item[3]].append(float(item[0][:2])*60.+float(item[0][3:5])+float(item[0][6:8])/60.+float(item[0][9:])/60000.)

for item in dex:
  count = 1
  ccount = 1
  if dex[item][len(dex[item])-1]-dex[item][0] <1: 
    count = len(dex[item]) 
  else:
    for t in range(len(dex[item])-1):
      for tt in range(len(dex[item])-t-1):
        if dex[item][tt+t+1]-dex[item][t] <1:
          ccount += 1
        else: break
      if ccount>count: 
        count=ccount
      ccount=1
  counts.append((item, count))

counts.sort(key=lambda x: x[0])
print('\n'.join([str(x[1]) for x in counts]))

输出:

2
3

我确实认为您可以通过使用Python的标准库来使您的生活将来更轻松:)