numpy.savetxt()在最后一行停止换行

2024-09-28 21:45:14 发布

您现在位置:Python中文网/ 问答频道 /正文

在numpy.savetxt()似乎总是在文件末尾加上一行新行。有什么好办法可以避免这种行为吗?将换行符替换为其他字符没有帮助。在

我不认为这对我的代码是特别的,但是编写是这样的(模型是一个3D数组):

np.savetxt(modelFile, model, delimiter=",", fmt='%.3f')

Tags: 文件代码模型numpymodelnp数组字符
2条回答

解决方案

为了回答这个问题:有一个很好的方法来避免这种行为,尽管这取决于你对友善的含义。基本上,您需要做的是将numpy.savetxt函数包装到另一个函数中,或者在需要的地方使用这里显示的代码块。在

我所做的是把@mgilson's code和{a2}混合起来回答另一个类似的问题。简而言之,下一步是使用numpy.savetxt保存文件并删除最后一行的代码:

import os

with open('some_array.txt', 'w') as fout:
    NEWLINE_SIZE_IN_BYTES = 1 # 2 on Windows?
    np.savetxt(fout, some_array) # Use np.savetxt.
    fout.seek(0, os.SEEK_END) # Go to the end of the file.
    # Go backwards one byte from the end of the file.
    fout.seek(fout.tell() - NEWLINE_SIZE_IN_BYTES, os.SEEK_SET)
    fout.truncate() # Truncate the file to this point.

os.SEEK_END和{}的定义可以找到here。虽然他们分别只有2和0。在

代码背后的逻辑

这里需要注意的是:

  • 文件以文本模式打开,而不是以二进制模式打开。这一点很重要,因为如果不指定编码(我们通常不会像对这个问题提供的两个答案那样)来指定编码,那么在文本模式下对文件的写入和读取是依赖于平台的。例如,换行符在Windows或Linux中的读取方式不同。从the documentation

    Normally, files are opened in text mode, that means, you read and write strings from and to the file, which are encoded in a specific encoding. If encoding is not specified, the default is platform dependent (see open()). (...)

    (...) In text mode, the default when reading is to convert platform-specific line endings (\n on Unix, \r\n on Windows) to just \n. When writing in text mode, the default is to convert occurrences of \n back to platform-specific line endings.

  • 在下一行代码fout.seek(0, os.SEEK_END)中,我们将文件的当前位置设置为文件的末尾(请参阅seek()的引用)。这是在文本模式下从文件末尾开始的唯一合法操作,我将在本文后面引用。

  • 然后,在fout.seek(fout.tell() - NEWLINE_SIZE_IN_BYTES, os.SEEK_SET)行中,我们只告诉Python:
    • 将当前位置从当前位置向后设置1个字节:fout.tell() - NEWLINE_SIZE_IN_BYTES。其中tell()只返回当前位置,正如您在reference中看到的那样。在
    • 从文件os.SEEK_SET的开头开始。在
  • 这样做的原因是在seek()方法中,只有tell()返回的偏移才是合法的,正如^{}文档中所说:

    If the file is opened in text mode (without ‘b’), only offsets returned by tell() are legal. Use of other offsets causes undefined behavior.

  • 最后,truncate()方法只将文件剪切到当前位置。在

另一种方式是二进制模式

我必须声明我现在还不太确定在文本模式下执行此操作是否比在二进制模式下更好尽管其他答案让我这么认为,请看另一个question。在

@mgilson's code之后,我们只需要以二进制模式打开文件。修改后的工作代码为:

^{pr2}$

在Python>;3.2的版本中,这两种方法都适用。在

我不太确定为什么这很重要,或者是否有一种方法可以在numpy端阻止它(我在文档中没有看到任何东西…),但是你可以在写完之后在文件中查找,然后截断。e、 g

NEWLINE_SIZE_IN_BYTES = -1  # -2 on Windows?
with open('data.dat', 'w') as fout:
    np.savetxt(fout, model, delimiter=",", fmt='%.3f')
    fout.seek(NEWLINE_SIZE_IN_BYTES, 2)
    fout.truncate()

注意:要向后搜索,字节大小必须为负数

相关问题 更多 >