【问题标题】:How to ignore alternate lineterminator in pandas read_csv?如何忽略 pandas read_csv 中的备用换行符?
【发布时间】:2021-08-22 11:56:39
【问题描述】:

我有一个文本文件,其中有很多行,每行有 6 列,但在每第四列和每 6 列之后都有一个 \n,类似于:

第 1 行 ---> 1 2 3 4\n 5 6\n

第 2 行 ---> 7 8 9 10\n 11 12\n

我正在使用命令从文件中创建数据框:

df = pd.read_csv('info.txt', header=None, delimiter=r"\s+", names = cols, lineterminator='\n')

但是,即使我在 read_csv 的 names 属性中明确提供了 6 列的名称,pandas read_csv 也会将上述数据读取为 4 行:

   col1 col2 col3 col4 col5 col6
0   1    2   3    4    NaN  NaN
1   5    6   NaN  NaN  NaN  NaN
2   7    8   9    10   NaN  NaN
3   11   12  NaN  NaN  NaN  NaN

如何读取数据:

   col1 col2 col3 col4 col5 col6
0   1    2   3    4    5    6
1   7    8   9    10   11   12

【问题讨论】:

  • 文件中的行终止符是什么?我的意思是 1 2 3 4\n 5 6\n 末尾的符号?你有一个 windows/mac 行尾(\r\r\n)吗?
  • 我在文本文件上做了一个 open('info.txt','r+b').read() ,我可以看到数字数据和模式中写入的 \n 字符,例如: 61 4 2 242\n 392 4\n ,所以行终止符应该是 \n 但它连续出现两次因此产生了问题。第二个 \n 之后没有其他区别符号,新行值以相同模式从第二个 \n 之后开始。
  • 你可能有一个非 unix 行尾(不是\n)。否则你会得到61 4 2 242392 4 作为单独的行。您可以尝试使用 stackoverflow.com/questions/3569997/… 找到行尾
  • 我跑了file info.txt,它给出了info.txt: ASCII text的响应,当我查看文件时,它显示61 4 2 242392 4作为单独的行。所以看起来 \n 只是行分隔符,但它没有与数据对齐。
  • 你在用macos吗?对我来说,只有一行 1 2 3 4\n 5 6\n 听起来是不可能的,而您的编辑器将其显示为单独的行,而 open() 将其显示为单独的行。您可以执行以下操作:在二进制查看器中检查换行符,例如 cat info.txt | od -c | less。我相信你有一个macos换行符(\r),你可以试试pd.read_csv(..., lineterminator='\r')

标签: python pandas


【解决方案1】:

从@gold_cy 的回答中获得灵感,能够通过为每个备用行扩展列表的最后一个元素而不是在列表中追加一个新行来解决问题:

def strip_newlines(fp):
    file_data_without_line_breaks = []
    i=-1
    with open(fp, "r") as fin:
        for val, line in enumerate(fin.readlines()):
            stripped_line = line.rstrip()
            if(val%2 == 1):
              file_data_without_line_breaks[i].extend(stripped_line.split())
            else:
              i=i+1
              file_data_without_line_breaks.append(stripped_line.split())
    return file_data_without_line_breaks

但这可能不适合大数据,因为列表对象是在内存中创建的。

【讨论】:

  • 通过这种方法,您还可以将数字作为字符串获取。
  • 是的,但我仍然可以使用 listVal = strip_newlines("info.txt") df = pd.DataFrame(listVal, columns=cols) 按预期创建数据框
【解决方案2】:

您可以使用自定义读取逻辑创建类似文件的对象。类文件对象必须包含 __iter__read 方法。

测试数据: echo -en '1 2 3 4\n 5 6\n 7 8 9 10\n 11 12\n' > info.txt

class MultiLineReader:
    def __init__(self, filename):
        self.filename = filename
        self.fd = None

    # use as context manager in order to open and close file correctly
    def __enter__(self):
        self.fd = open(self.filename, 'r')
        return self

    def __exit__(self, type, value, traceback):
        self.fd.close()

    # file-like object must have this method
    def __iter__(self):
        while True:
            line = self.readline()
            if not line:
                break
            yield line

    # file-like object must have this method
    # just read a line 
    def read(self, size=-1):
        return self.readline()

    # read two lines at a time
    def readline(self):
        return self.fd.readline().strip() + self.fd.readline()

# example usage
with MultiLineReader("info.txt") as f:
    pd.read_csv(f, sep=r'\s+', header=None)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 1970-01-01
    • 2019-01-31
    • 2021-08-06
    • 2020-12-30
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多