2

我正在编写一个接受(可能很大)文件的 Python 脚本。以下是可以格式化输入文件的方式的示例:

class1 1:v1 2:v2 3:v3 4:v4 5:v5
class2 1:v6 4:v7 5:v8 6:v9
class1 3:v10 4:v11 5:v12 6:v13 8:v14
class2 1:v15 2:v16 3:v17 5:v18 7:v19

其中class1 和class2 是一些数字,例如1 和-1。(好奇的用户可能会注意到这是一个与 LIBSVM 相关的文件,但在这种情况下不需要了解软件。)值 v1、v2、...、v19 表示任何整数或浮点值。显然,就总行数和每行长度而言,我的文件会比这大得多,这就是我在这里关心效率的原因。

我正在尝试检查冒号左侧的最大值是什么。在 LIBSVM 中,这些被称为“特征”并且在这里总是整数。例如,在我上面概述的示例中,第 1 行的最大特征是 5。第 2 行的最大特征为 6,第 3 行的最大特征为 8,最后,第 4 行的最大特征为 7。因为 8 是这些值中的最大值,所以这是我想要的值。我正在查看一个文件,行可能包含数千个特征,并且有数十万

该文件满足以下属性:

  1. 特征必须严格增加。即允许“3:v1 4:v2”,但不允许“3:v1 3:v2”。
  2. 这些特征不一定是连续的,可以跳过。在我给出的第一个示例中,第一行具有连续顺序 (1,2,3,4,5) 的特征并跳过特征 6、7 和 8。其他 3 行没有连续顺序的特征。没关系,只要这些功能严格增加。

现在,我的方法是检查每一行,用空格分隔每一行,用冒号分隔最后一项,然后检查特征值。之后,我会执行一个程序来检查此类 featureNum 的最大值。

file1 = open(...)
max = 0
for line in file1:
    linesplit = line.rstrip('\n').split(' ')
    val = linesplit[len(linesplit) - 1]
    valsplit = val.split(':')
    featureNum = valsplit[0]
    if (featureNum > max):
        max = featureNum
 print max
 file1.close()

但我希望有一种更好或更有效的方法来做到这一点,例如通过仅获取直接在换行符之前的那些术语来分析文件的某种方法(也许是为了避免阅读所有行?)。我是 Python 新手,所以如果我错过了一些明显的东西,我不会感到惊讶。

可能的参考:http ://docs.python.org/library/stdtypes.html

4

1 回答 1

1

由于您不关心一行中的所有功能,而只关心最后一个,因此您不需要拆分整行。我不知道这是否真的更快,你需要计时看看。它绝对不像分割整条线那样 Pythonic。

def last_feature(line):
    start = line.rfind(' ') + 1
    end = line.rfind(':')
    return int(line[start:end])

with open(...) as file1:
    largest = max(last_feature(line) for line in file1)
于 2012-07-10T16:45:44.710 回答