Python 将txt文件解析为字典以写入csv文件

Python 将txt文件解析为字典以写入csv文件,python,csv,file-io,Python,Csv,File Io,EPROM输出一个.txt文件,如下所示: *** Header Start *** VersionPersist: 1 LevelName: Session Subject: 7 Session: 1 RandomSeed: -1983293234 Group: 1 Display.RefreshRate: 59.654 *** Header End *** Level: 2 *** LogFrame Start *** MeansEffectBias: 7 P

EPROM输出一个.txt文件,如下所示:

*** Header Start *** VersionPersist: 1 LevelName: Session Subject: 7 Session: 1 RandomSeed: -1983293234 Group: 1 Display.RefreshRate: 59.654 *** Header End *** Level: 2 *** LogFrame Start *** MeansEffectBias: 7 Procedure: trialProc itemID: 7 bias1Answer: 1 *** LogFrame End *** Level: 2 *** LogFrame Start *** MeansEffectBias: 2 Procedure: trialProc itemID: 2 bias1Answer: 0 ***标题开始*** 版本持久化:1 LevelName:会话 主题:7 会议:1 随机种子:-1983293234 组别:1 显示刷新率:59.654 ***收割台端*** 级别:2 ***对数帧开始*** 平均效应偏差:7 程序:trialProc 项目编号:7 答案:1 ***对数框架端*** 级别:2 ***对数帧开始*** 平均效应偏差:2 程序:trialProc 项目编号:2 答案:0 我想解析它并将其写入一个.csv文件,但删除了许多行

我试图创建一个字典,将冒号前出现的文本作为键,然后 后面的文本作为值:

{subject: [7, 7], bias1Answer : [1, 0], itemID: [7, 2]} {主题:[7,7],BIAS1答案:[1,0],项目ID:[7,2]} def加载_数据(文件名): 数据={} eprome=open(文件名'r') 对于EPROM中的行: rows=re.sub('\s+','',line).strip().split(':')) 尝试: 数据[行[0]]+=行[1] 除KeyError外: 数据[行[0]]=行[1] eprome.close() 返回数据 对于打开的行(文件名为“r”): 如果行中有“:”: 行=行.strip().split(“:”) fullDict[行[0]]=行[1] 打印全文 以下两个脚本都会产生垃圾:

{'\x00\t\x00M\x00e\x00a\x00n\x00s\x00E\x00f\x00f\x00e\x00c\x00t\x00B\x00i\x00a\x00s\x00': '\x00 \x005\x00\r\x00', '\x00\t\x00B\x00i\x00a\x00s\x002\x00Q\x00.\x00D\x00u\x00r\x00a\x00t\x00i\x00o\x00n\x00E\x00r\x00r\x00o\x00r\x00': '\x00 \x00-\x009\x009\x009\x009\x009\x009\x00\r\x00' \0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\x009\x009\x009\x009\x009\x00\r\x00' 如果我可以设置字典,我可以将其写入csv文件,如下所示!!:

Subject itemID ... bias1Answer 7 7 1 7 2 0 主题项目ID…BIAS1答案 7 7 1 7 2 0
您不需要创建字典

import codecs
import csv

with codecs.open('eprime.txt', encoding='utf-16') as f, open('output.csv', 'w') as fout:
    writer = csv.writer(fout, delimiter='\t')
    writer.writerow(['Subject', 'itemID', 'bias1Answer'])
    for line in f:
        if ':' in line:
            value = line.split()[-1]

        if 'Subject:' in line:
            subject = value
        elif 'itemID:' in line:
            itemID = value
        elif 'bias1Answer:' in line:
            bias1Answer = value
            writer.writerow([subject, itemID, bias1Answer])

第二种方法可行,但每个字典键的值都应该是一个列表。当前,对于字典中的每个键,您只存储一个值,结果只存储最后一个值。您可以修改代码,使每个键的值都是一个列表。 以下代码将实现同样的效果:

for line in open(fileName, 'r'):
    if ':' in line:
        row = line.strip().split(':')
        # Use row[0] as a key, initiate its value
        # to be a list and add row[1] to the list. 
        # In case already a key 'row[0]'
        # exists append row[1] to the existing value list
        fullDict.setdefault(row[0],[]).append(row[1])
print fullDict 

似乎EPROM输出是用utf-16编码的

>>> print '\x00\t\x00M\x00e\x00a\x00n\x00s\x00E\x00f\x00f\x00e\x00c\x00t\x00B\x00i\x00a\x00s\x00'.decode('utf-16-be')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/encodings/utf_16_be.py", line 16, in decode
    return codecs.utf_16_be_decode(input, errors, True)
UnicodeDecodeError: 'utf16' codec can't decode byte 0x00 in position 32: truncated data
>>> print '\x00\t\x00M\x00e\x00a\x00n\x00s\x00E\x00f\x00f\x00e\x00c\x00t\x00B\x00i\x00a\x00s\x00'.decode('utf-16-be', 'ignore')
    MeansEffectBias
>>打印'\x00\t\x00M\x00e\x00a\x00n\x00s\x00e\x00f\x00f\x00e\x00c\x00t\x00B\x00i\x00a\x00s\x00'。解码('utf-16-be')
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib/python2.7/encodings/utf_16_be.py”,第16行,解码
返回编解码器。utf_16_be_解码(输入,错误,真)
UnicodeDecodeError:“utf16”编解码器无法解码位置32:截断数据中的字节0x00
>>>打印“\x00\t\x00M\x00e\x00a\x00n\x00s\x00e\x00f\x00f\x00e\x00c\x00t\x00B\x00i\x00a\x00s\x00”。解码('utf-16-be','ignore')
平均效应偏差

我知道这是一个比较老的问题,所以你可能早就解决了这个问题,但我认为你正在以一种比需要更复杂的方式处理这个问题。我想,如果其他人也有同样的问题并发现了这个问题,我会做出回应

如果您这样做是因为您没有软件密钥,那么了解eprome的E-MergeE-DataAid程序不需要密钥可能会有所帮助。您只需要用于编辑生成文件的密钥。向您提供.txt文件的人可能都应该有这些程序的安装盘。如果没有,可以在PST网站上找到(我相信你需要一个序列码来创建一个帐户,但不确定)

Eprime通常会创建一个
.edat
文件,该文件与您发布示例的文本文件的内容相匹配。但有时,如果Eprime崩溃,您无法获得edat文件,而只有
.txt
文件。幸运的是,您可以从
.txt
文件生成edat文件

我将如何处理这个问题:

  • 如果您没有可用的edat文件,请首先使用E-DataAid恢复文件

  • 然后假设您有多个参与者,您可以使用E-Merge将完成此任务的所有参与者的所有edat文件合并在一起

  • 打开合并后的文件。它可能看起来有点混乱,这取决于文件中有多少。你可以进入工具->排列列。这将显示所有变量的列表

  • 调整,使右侧框中只有所需的变量。点击“确定”

  • 然后你应该有一些类似于你最终目标的东西,可以作为csv导出

  • 如果程序中有许多过程,此时可能会在变量或兴趣所在的位置有只包含启动信息和
    NULL
    的行。您可以通过转到工具->过滤器并创建过滤器来消除这些行来解决此问题

    for line in open(fileName, 'r'):
        if ':' in line:
            row = line.strip().split(':')
            # Use row[0] as a key, initiate its value
            # to be a list and add row[1] to the list. 
            # In case already a key 'row[0]'
            # exists append row[1] to the existing value list
            fullDict.setdefault(row[0],[]).append(row[1])
    print fullDict 
    
    >>> print '\x00\t\x00M\x00e\x00a\x00n\x00s\x00E\x00f\x00f\x00e\x00c\x00t\x00B\x00i\x00a\x00s\x00'.decode('utf-16-be')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python2.7/encodings/utf_16_be.py", line 16, in decode
        return codecs.utf_16_be_decode(input, errors, True)
    UnicodeDecodeError: 'utf16' codec can't decode byte 0x00 in position 32: truncated data
    >>> print '\x00\t\x00M\x00e\x00a\x00n\x00s\x00E\x00f\x00f\x00e\x00c\x00t\x00B\x00i\x00a\x00s\x00'.decode('utf-16-be', 'ignore')
        MeansEffectBias