【问题标题】:Columns not separated by comma when converting multiple .txt files into .csv files in Python在 Python 中将多个 .txt 文件转换为 .csv 文件时,列未用逗号分隔
【发布时间】:2016-12-06 09:13:18
【问题描述】:

我有一个文件夹,里面有 4000 个 txt 时间序列数据文件,我想使用 Pandas 等进行分析。我已经能够重命名它们并将它们转换为 csv 文件,但是这些列的分组不正确。我在这里浏览了几篇文章并观看了几个关于解析 txt 文件等的视频,但到目前为止我没有尝试过任何工作。

这是其中一个 txt 文件的示例。我在记事本中看不到前导或尾随空格、制表符或换行符:

这是我正在处理的代码,主要来自here

file = 'patient0.txt'
csv_f = "patient0.csv"
with open(file,'r') as in_txt:
        stripped = (line.strip() for line in in_txt)
        lines = (line for line in stripped if line)
        grouped = zip(*[lines]*3)
        with open(csv_f,'w') as out_file:
            writer = csv.writer(out_file)
            writer.writerows(grouped)

这是生成的 csv 文件。

这是我需要的格式:

我今天刚刚了解了生成器。这是我将它们转换为列表时的结果:

【问题讨论】:

  • 您能否详细说明分组不是您想要的样子?是不是有3个逗号分隔的字段在一起?在 Excel 中打开时多余的行?
  • 问题是数据如何被错误地拆分为三列,并且仅以每三个逗号分隔。还有额外的一行。
  • 看起来您的原始数据已经只是普通的 CSV 格式?您从另一个问题中获得的代码是为什么要这样分组。如果您只是在其中一个文件上运行 pd.read_csv() 会发生什么?
  • 好的。我不知道为什么我最初没有尝试过。谢谢!

标签: python csv pandas


【解决方案1】:

** 编辑 **

我刚刚意识到这不会产生您所追求的确切格式。保留它以防其他人发现它有用

** 编辑 **

您正在查看的数据看起来像是使用键值对的自定义格式。我不知道你是否想使用 csv 模块来读取这些文件。 (虽然在编写输出 csv 文件时非常有用)

格式如下:

不同的行可能有不同的参数(无法从您提供的非常小的数据 sn-p 中分辨出来)。看起来您在文件的前面添加了“时间、参数、值”,这就是我们看到奇怪的“值00:00”条目的原因。我认为您的意思是在 Value 之后添加一个换行符。

我制作了一个包含一些数据的虚拟文件,因为我认为你拥有它:

00:00, RecordID,5,Age,73
00:42,PaCO2,3400:42,PaO2,34401:11
01:11,SysABP,10501:11,Temp,35.201:11

在这里,我们希望输出 csv 文件具有的唯一列名是

RecordID, Age, PaCO2, PaO2, SysABP, Temp

我们需要遍历文件以发现所有这些。找到它们后,我们可以创建一个带有适当列的 csv.DictWriter。然后我们再次循环输入文件,将我们看到的所有内容写入 dict。

我在上面创建的虚拟文件上成功测试了这个脚本。希望从脚本中的 cmets 可以清楚地看出发生了什么。

import csv


def txt_to_csv(input_filenames):

    for input_filename in input_filenames:
        column_names = set()
        output_filename = input_filename[:-4] + '.csv'
        with open(input_filename, 'rb') as in_txt:

            # figure out which column names are in the file on at least one line
            for line in in_txt:

                # get a list of parameters that were split by comma in the input txt file
                params = line.strip().split(",")

                # lines[1::2] slices out every other entry starting with the first column name
                # we or the entries into the set to keep our memory footprint small by only
                # storing one copy of each unique column name
                # we strip each entry of any extra whitespace while doing a set comprehension.
                column_names |= set(params[1::2])

                # notice that we always skip the first column with the timestamp by starting at 1

            # strip off any extra whitespace in column names
            column_names = {x.strip() for x in column_names}

            # add in missing timestamp column to the column names
            column_names.add('timestamp')

            # sort column names and convert python3 strings to bytes as required by csv module
            sorted_column_names = sorted(column_names)

            # bring the pointer back to the beginning of the file
            in_txt.seek(0, 0)

            # open a csv file and start writing the output
            with open(output_filename, 'wb') as out_csv:
                writer = csv.DictWriter(out_csv, sorted_column_names, dialect='excel')

                # write column names
                writer.writeheader()

                for line in in_txt:
                    # create a list of values for this line
                    params = [x.strip() for x in line.strip().split(",")]

                    # turn key value pairs into dictionary
                    row_dict = dict(zip(params[1::2], params[2::2]))

                    # write timestamp entry to the dictionary
                    row_dict['timestamp'] = params[0]

                    # write row to file
                    writer.writerow(row_dict)


if __name__ == '__main__':
    input_filenames = [r'C:\Users\cruse\Desktop\dummy_data.txt']
    txt_to_csv(input_filenames)

我得到的输出是

Age PaCO2       PaO2      RecordID  SysABP      Temp            timestamp
73                        5                                     0:00
    3400:42:00  34401:11                                        0:42
                                    10501:11    35.201:11       1:11

这对这个数据集是正确的。然后,您将使用 Pandas 之类的工具通过时间传播价值。 (即使用 pd.fillna 将相同的 RecordID 分配给所有后续行)

如果您希望它处理更多文件,只需在底部的 input_filenames 列表中添加更多路径即可。

【讨论】:

    【解决方案2】:

    原始 csv 中的冒号似乎代表新行,因此将原始文本文件中的这些冒号转换为新行,然后将其保存为 csv。然后应该使用以下方法轻松解析:

    将熊猫导入为 pd

    df = pd.read_csv(csv_file_name)

    【讨论】:

      猜你喜欢
      • 2018-04-03
      • 1970-01-01
      • 2013-11-14
      • 2019-03-13
      • 2018-11-05
      • 2012-09-18
      • 1970-01-01
      • 2021-08-28
      • 1970-01-01
      相关资源
      最近更新 更多