1

我有一个像下面这样的文件。

0       0       0 
0.00254 0.00047 0.00089
0.54230 0.87300 0.74500 
0       0       0

我想修改这个文件。如果值小于 0.05,则值为 1。否则,值为 0。

python脚本运行后,文件应该是这样的

1       1        1
1       1        1
0       0        0
1       1        1

你能帮帮我吗?

4

4 回答 4

4

好的,既然您是 StackOverflow 的新手(欢迎!),我将引导您完成此操作。我假设您的文件名为test.txt.

with open("test.txt") as infile, open("new.txt", "w") as outfile:

打开我们需要的文件,我们的输入文件和一个新的输出文件。该with语句确保在退出块后关闭文件。

    for line in infile:

逐行循环文件。

        values = [float(value) for value in line.split()]

现在这更复杂了。每行包含空格分隔的值。可以使用 将它们拆分为字符串列表line.split()。但它们仍然是字符串,所以必须先转换为floats。所有这些都是通过列表理解完成的。结果是,例如,在以这种方式处理第二行之后,values现在是以下列表:[0.00254, 0.00047, 0.00089].

        results = ["1" if value < 0.05 else "0" for value in values]

现在我们正在创建一个名为 的新列表results。每个元素都对应于 的一个元素values,如果它是一个,如果不是,"1"它就是一个。value < 0.05"0"

        outfile.write("      ".join(results))

将“整数字符串”列表转换回字符串,每个字符串由 7 个空格分隔。

        outfile.write("\n")

添加一个换行符。完毕。


如果您不介意额外的复杂性,这两个列表推导可以合并为一个:

        results = ["1" if float(value) < 0.05 else "0" for value in line.split()]
于 2013-03-04T14:47:37.670 回答
2

如果您可以使用库,我建议您使用 numpy :

import numpy as np
myarray = np.genfromtxt("my_path_to_text_file.txt")
my_shape = myarray.shape()
out_array = np.where(my_array < 0.05, 1, 0)
np.savetxt(out_array)

您可以将格式添加为 savetxt 函数的参数。该函数的文档字符串非常易于解释。

如果你被纯 python 困住了:

with open("my_path_to_text_file") as my_file:
    list_of_lines = my_file.readlines()
    list_of_lines = [[int( float(x) < 0.05) for x in line.split()] for line in list_of_lines]

然后将该列表写入您认为合适的文件。

于 2013-03-04T14:49:53.413 回答
0

您可以使用此代码

f_in=open("file_in.txt", "r")       #opens a file in the reading mode
in_lines=f_in.readlines()           #reads it line by line
out=[]
for line in in_lines:
    list_values=line.split()        #separate elements by the spaces, returning a list with the numbers as strings
    for i in range(len(list_values)):
        list_values[i]=eval(list_values[i])     #converts them to floats
#       print list_values[i],
        if list_values[i]<0.05:     #your condition
#           print ">>", 1
            list_values[i]=1
        else:
#           print ">>", 0
            list_values[i]=0
    out.append(list_values)         #stores the numbers in a list, where each list corresponds to a lines' content
f_in.close()                        #closes the file

f_out=open("file_out.txt", "w")     #opens a new file in the writing mode
for cur_list in out:
    for i in cur_list:
        f_out.write(str(i)+"\t")    #writes each number, plus a tab
    f_out.write("\n")               #writes a newline
f_out.close()                       #closes the file
于 2013-03-04T14:57:08.670 回答
0

以下代码就地执行替换:为此,文件以'rb+'模式打开。绝对必须以二进制模式打开它b+in'rb+'表示可以在文件中写入和读取。注意模式也可以写'r+b'

但是使用'rb+'很尴尬:

  • 如果您使用 读取for line in f,则文件将按块读取,并且将几行保留在缓冲区中,它们实际上是一个接一个地读取,直到另一块数据被读取并加载到缓冲区中。这使得执行转换变得更加困难,因为必须在 的帮助下跟随文件指针的位置tell()并移动指针,seek()事实上我还没有完全理解它必须如何完成。
    .
    令人高兴的是,有一个解决方案replace(),因为,我不知道为什么,但我相信事实,当readline()读取一行时,文件的指针在磁盘上不会比行尾更远(也就是说它停在换行符处)。
    现在很容易移动和知道文件指针的位置

  • 读后写,必须要seek()执行,即使应该执行,也就是seek(0,1)从实际位置移动0个字符。那必须改变文件指针的状态,类似的。

好吧,对于你的问题,代码如下:

import re
from os import fsync
from os.path import getsize

reg = re.compile('[\d.]+')

def ripl(m):
    g = m.group()
    return ('1' if float(g)<0.5 else '0').ljust(len(g))

path = ...........'

print 'length of file before : %d' % getsize(path)

with open('Copie de tixti.txt','rb+') as f:
    line = 'go'
    while line:
        line = f.readline()
        lg = len(line)
        f.seek(-lg,1)
        f.write(reg.sub(ripl,line))
        f.flush()
        fsync(f.fileno())

print 'length of file after : %d' % getsize(path)

flush()并且fsync()必须被执行以确保指令在被命令f.write(reg.sub(ripl,line))的那一刻有效地写入。

请注意,我从未管理过以 unicode 编码的文件。这当然更加困难,因为每个 unicode 字符都编码在几个字节上(在 UTF8 的情况下,字节数取决于字符)

于 2013-03-04T19:37:46.837 回答