【问题标题】:How to find min/max values from rows and columns in Python?如何从 Python 中的行和列中查找最小值/最大值?
【发布时间】:2011-12-12 21:09:49
【问题描述】:

我想知道如何从数据集(基本上是一个文本文件)中找到最小值和最大值。它有 50 行,50 列。

我知道我可以设置一个控制循环(具体来说是 for 循环)让它读取每一行和每一列,并确定最小/最大值。但是,我不知道该怎么做。

我认为需要先将行和列转换为列表,然后我需要使用split() 函数。我尝试如下设置,但似乎不起作用:

for x in range(4,50): # using that range as an example
    x.split()
    max(4,50)
    print x

Python 新手。请原谅我的错误。

【问题讨论】:

  • 文件的外观如何?你能提供文件的一部分吗?
  • Here's 我编写的一个脚本,它读取文件中的所有行,将其放在列表中并循环遍历列表。这不是您要查找的程序,但它可能对您有所帮助。
  • @Griffin:对不起,我应该提到它是一个 ASCII 数据集。这是一个示例 - cl.ly/BBqr
  • 你想要每行的最小值和最大值,还是整个数据集的最小值和最大值,或者只是什么?您要排除的前几行/列有什么特别之处吗?数据大小有什么特别之处吗?通常,程序员会尽可能地忽略他们“知道”输入数据大小的内容,而更愿意编写可以处理任意数量数据的东西(无论如何,这通常同样简单,甚至更容易)。
  • @KarlKnechtel 我需要确定整个数据集的最小值/最大值。

标签: python max min


【解决方案1】:

如果文件包含一个常规(矩形)矩阵,并且您知道它包含多少行标题信息,那么您可以跳过标题信息并使用NumPy 非常容易地做到这一点:

import numpy as np

f = open("file.txt")
# skip over header info
X = np.loadtxt(f)
max_per_col = X.max(axis=0)
max_per_row = X.max(axis=1)

【讨论】:

    【解决方案2】:

    试试这样的:

    data = []
    with open('data.txt') as f:
        for line in f:                   # loop over the rows
            fields = line.split()        # parse the columns
            rowdata = map(float, fields) # convert text to numbers
            data.extend(rowdata)         # accumulate the results
    print 'Minimum:', min(data)
    print 'Maximum:', max(data)
    

    注意 split() 如果您想在除空格以外的其他内容(例如逗号)上进行拆分,则需要一个可选参数。

    【讨论】:

    • 来自《算法简介》一书,又名 CLRS,如果我们必须同时找到最小值和最大值,则最多可以使用 3 * (n // 2) 比较而不是 2 * n - 2. python 应该提供类似 minmax() 的东西吗?
    • @sunqiang,比较的次数可以减少25%,真是太酷了。虽然放到 Python 内核中还不够重要,但它是一个有趣的算法,所以我在 code.activestate.com/recipes/577916-fast-minmax-function 发布了示例代码
    • @Raymond Hettinger,感谢您在这么短的时间内提供食谱。另一个很酷的 itertools 示例,:P
    • @RaymondHettinger - 谢谢。我在代码中注意到了您的 cmets,但只是为了让我正确理解这一点,如果可以,您能否详细说明 fields = line.split()?我之前没有使用过map 函数。我刚刚在 Python Docs 上读到了它。那基本上是先将文本放入列表然后将它们转换为数字吗?
    • 感谢这段代码。它完美地剪切/粘贴到我正在处理的脚本中(只需稍作修改即可满足我的需求)!
    【解决方案3】:

    嗯...你确定 在这里不适用吗? ;) 无论如何:

    您不仅需要拆分输入行,还需要将文本值转换为数字。 因此,假设您已将输入行读入 in_line,您将执行以下操作:

    ...
    row = [float(each) for each in in_line.split()]
    rows.append(row) # assuming you have a list called rows
    ...
    

    获得行列表后,您需要获取列:

    ...
    columns = zip(*rows)
    

    然后您可以遍历调用 max() 的每一行和每一列:

    ...
    for each in rows:
        print max(each)
    for eac in columns:
        print max(each)
    

    编辑:下面是更完整的代码,展示了如何打开文件、遍历文件的行、关闭文件以及使用上述提示:

    in_file = open('thefile.txt', 'r')
    
    rows = []
    for in_line in in_file:
        row = [float(each) for each in in_line.split()]
        rows.append(row)
    
    in_file.close() # this'll happen at the end of the script / function / method anyhow
    
    columns = zip(*rows)
    
    for index, row in enumerate(rows):
        print "In row %s, Max = %s, Min = %s" % (index, max(row), min(row))
    
    for index, column in enumerate(columns):
        print "In column %s, Max = %s, Min = %s" % (index, max(column), min(column))
    

    编辑:为了新学校的好处,不要使用我旧的、有风险的文件处理。使用新的安全版本:

    rows = []
    with open('thefile.txt', 'r') as in_file:
        for in_line in in_file:
            row = ....
    

    现在,您得到了很多保证,即使您在读取文件时抛出异常,您也不会不小心做坏事,例如让文件保持打开状态。另外,您可以完全跳过in_file.close(),而不会感到内疚。

    【讨论】:

    • 对不起,是的,我应该标记那个。我是 Python 新手,一直在练习,但有时需要帮助。这次真是万分感谢。这多少有点道理。我会试试这个并在这里发布我的最终代码。
    • 我唯一要补充的就是考虑使用csv 模块,但这同样有效。
    • @kolor - 没问题 - 我只是闻到了家庭作业的味道! :) 显然,要找到最小值,您还需要遍历调用 min()。
    • @AustinMarshall - 我做了 2 个假设:1)空间分隔值和 2)本练习的重点是处理数据,而不是从文件中读取数据。我使用并喜欢csv,但不想在这里进入它。
    • @gomad 在我可以使用in_line.split()之前...我需要定义in_line,对吧?所以我使用in_line = f.readlines() 但我收到以下错误:AttributeError: 'list' object has no attribute 'split'
    【解决方案4】:

    这对你有用吗?

    infile = open('my_file.txt', 'r')
    file_lines = file.readlines(infile)
    
    for line in file_lines[6:]:
        items = [int(x) for x in line.split()]
        max_item = max(items)
        min_item = min(items)
    

    【讨论】:

    • 您好 jcfollower,谢谢。你能详细说明 items = [in(x) for x in line.split()] 吗?它基本上是在尝试查找文件中的所有整数值吗?
    • [int(x) for x in line.split()] 表示“一个列表,包含将int 应用于line.split() 中的每个x 的结果”。 line.split() 将文本分解为空格,以便您拥有“单词”列表。 int 尝试将给出的文本解释为整数。所以这是从给定行上的每个“单词”创建一个整数。如果文件的该部分中有任何垃圾,它将大声失败。 ([6:] 部分基本上是跳过标题信息。)
    • @KarlKnechtel 谢谢你的解释!
    • @jcfollower,我已经在我的数据集 (cl.ly/BBqr) 上对此进行了测试,但它似乎选择了错误的值。根据我的数据集,仅在 Notepad++ 中查看,最大值应为 232,最小值应为 15。但程序显示 171 为最大值,22 为最小值。
    • for 循环为每一行重复设置max_itemmin_item。假设您将在 for 循环中使用这些值每行做更多的工作。要获得整个数据集的最大值和最小值,您需要通过创建包含整个数据集的 items 将它们一次全部传递给 maxmin。你应该能够想办法做到这一点。提示:尝试显式使用.readline 跳过标题,然后使用.read 将文件的其余部分读入单个字符串。 line.split() 技巧会将换行符视为空格。
    猜你喜欢
    • 2015-06-29
    • 2022-06-16
    • 2019-03-17
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    相关资源
    最近更新 更多