在CSV中查找某一列的最大值并添加新数据

3

两个小时前,我提出了一个关于从网站读写数据的问题。自那以后的两个小时里,我一直在寻找一种方法来读取输出列'A'中的最大日期值,将该值与刷新后的网站数据进行比较,并将任何新数据追加到csv文件中而不覆盖旧数据或创建重复项。

目前100%工作的代码如下:

import requests
symbol = "mtgoxUSD"
url = 'http://api.bitcoincharts.com/v1/trades.csv?symbol={}'.format(symbol)
data = requests.get(url)
with open("trades_{}.csv".format(symbol), "r+") as f:
    f.write(data.text)

我尝试了各种方法来查找列'A'的最大值。我尝试了使用“Dict”和其他排序/查找最大值的不同方式,甚至使用pandas和numpy库。但都没有成功。请问有人能指点一个从.csv文件中查找列最大值的好方法吗?谢谢!


这更像是一个问题而不是解决方案,但你不能做类似这样的事情吗:import csv,然后执行你的open行,然后在此之后执行whole_thing = list(csv.reader(f)),然后你就有了一个列表的列表。一旦你有了一个列表的列表,你就可以切片你想要的列(即whole_thing[some_line][column-with-data-we-want]),并取其中的最大值? - erewok
3个回答

2

如果您有一个 pandas DataFrame,您可以像这样获取任何列的最大值:

>>> max(data['time'])
'2012-01-18 15:52:26'

其中data是DataFrame的变量名称,time是列的名称。


1
似乎像这样的东西应该可以运行:

import requests
import csv
symbol = "mtgoxUSD"
url = 'http://api.bitcoincharts.com/v1/trades.csv?symbol={}'.format(symbol)
data = requests.get(url)
with open("trades_{}.csv".format(symbol), "r+") as f:
    all_values = list(csv.reader(f))
    max_value = max([int(row[2]) for row in all_values[1:]])
(write-out-the-value?)

修改:我使用了"row[2]",因为这是我在csv中取最大值的示例列。此外,我还必须剥离掉所有文本的列标题,这就是为什么我从第二行的"all_values[1:]"开始查看到文件末尾。


你应该了解一下“生成器表达式”……你会喜欢它们的!它们的工作方式与列表推导式非常相似,但它们可能更快,因为它们做的工作更少(它们不构建列表,只是逐个产生值)。此外,你实际上不需要调用list();请参考我的答案,了解从迭代器中丢弃一个或多个值的几种方法。 - steveha

1
我将为您提供两个答案,一个只返回最大值,另一个返回包含最大值的CSV行。
import csv
import operator as op
import requests

symbol = "mtgoxUSD"
url = 'http://api.bitcoincharts.com/v1/trades.csv?symbol={}'.format(symbol)
csv_file = "trades_{}.csv".format(symbol)

data = requests.get(url)
with open(csv_file, "w") as f:
    f.write(data.text)

with open(csv_file) as f:
    next(f) # discard first row from file -- see notes
    max_value = max(row[0] for row in csv.reader(f))

with open(csv_file) as f:
    next(f) # discard first row from file -- see notes
    max_row = max(csv.reader(f), key=op.itemgetter(0))

注释:

  • max()可以直接使用迭代器,而csv.reader()给我们提供了一个迭代器,所以我们可以直接传入。我假设您可能需要丢弃标题行,因此我展示了如何执行此操作。如果您有多个标题行要丢弃,则可能需要使用itertools模块中的islice()

  • 在第一个示例中,我们使用“生成器表达式”从每一行选择一个值,并找到最大值。这非常类似于“列表推导”,但它不会构建整个列表,它只允许我们迭代结果值。然后,max()消耗可迭代对象,我们得到最大值。

  • max()可以使用key=参数,其中您指定“键函数”。它将使用键函数获取值并使用该值来确定最大值...但是max()返回的值将是未修改的原始值(在本例中为CSV中的行值)。在这种情况下,键函数由operator.itemgetter()为您制作...您传入要获取的列,operator.itemgetter()为您构建一个获取该列的函数。

结果函数相当于:

def get_col_0(row):
    return row[0]
max_row = max(csv.reader(f), key=get_col_0)

或者,人们会使用lambda来实现这个功能:

max_row = max(csv.reader(f), key=lambda row: row[0])

但我认为operator.itemgetter()很方便,易于阅读。而且它速度很快。

  • 我展示了如何将数据保存在文件中,然后再从文件中提取数据。如果你想在不保存数据的情况下遍历数据,只需要按行迭代即可。

也许可以这样:

text = data.text
rows = [line.split(',') for line in text.split("\n") if line]
rows.pop(0)  # get rid of first row from data
max_value = max(row[0] for row in rows)
max_row = max(rows, key=op.itemgetter(0))
  • 我不知道你想要哪一列... "A"列可能是第0列,所以上面使用了0。根据需要替换列数。

我喜欢这些解决方案。感谢您的解释。 - erewok
同意。感谢详细解释步骤! - Daniel Henry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接