使用带有字段说明符的Pandas将平面文件读取到DataFrames

时间:2014-01-17 18:08:12

标签: python pandas

我正在尝试使用pandas将平面文件读入DataFrame,但似乎无法使格式正确。我的文件每行代表一个可变数量的字段,如下所示:

TIME=20131203004552049|CHAN=FCJNJKDCAAANPCKEAAAAAAAA|EVNT=NVOCinpt|MIME=application/synthesis+ssml|TXID=NUAN-20131203004552049-FCJNJKDCAAANPCKEAAAAAAAA-txt|TXSZ=1167|UCPU=31|SCPU=15
TIME=20131203004552049|CHAN=FCJNJKDCAAANPCKEAAAAAAAA|EVNT=NVOCsynd|INPT=1167|DURS=5120|RSTT=stop|UCPU=31|SCPU=15
TIME=20131203004552049|CHAN=FCJNJKDCAAANPCKEAAAAAAAA|EVNT=NVOClise|LUSED=0|LMAX=100|OMAX=95|LFEAT=tts|UCPU=0|SCPU=0

我在|处有字段分隔符,我已将所有唯一键的列表提取到keylist,并尝试使用以下内容读取数据:

keylist = ['TIME',
             'CHAN',
             # [truncated]
             'DURS',
             'RSTT']

test_fp = 'c:\\temp\\test_output.txt'
df = pd.read_csv(test_fp, sep='|', names=keylist)

这错误地构建了DataFrame,因为我没有指定任何方法来识别行中的键标签。我有点陷入困境,不确定研究的方式 - 我应该使用.read_json()吗?

1 个答案:

答案 0 :(得分:2)

不确定是否有一种灵巧的方式来做到这一点。有时,当数据结构与标准不同时,最容易在Python端对其进行预处理。当然,它没有那么快,但由于你可以立即以更标准的格式保存它,通常不值得担心。

一种方式:

with open("wfield.txt") as fp:
    rows = (dict(entry.split("=",1) for entry in row.strip().split("|")) for row in fp)
    df = pd.DataFrame.from_dict(rows)

产生

>>> df
                       CHAN  DURS      EVNT  INPT LFEAT LMAX LUSED  \
0  FCJNJKDCAAANPCKEAAAAAAAA   NaN  NVOCinpt   NaN   NaN  NaN   NaN   
1  FCJNJKDCAAANPCKEAAAAAAAA  5120  NVOCsynd  1167   NaN  NaN   NaN   
2  FCJNJKDCAAANPCKEAAAAAAAA   NaN  NVOClise   NaN   tts  100     0   

                         MIME OMAX  RSTT SCPU               TIME  \
0  application/synthesis+ssml  NaN   NaN   15  20131203004552049   
1                         NaN  NaN  stop   15  20131203004552049   
2                         NaN   95   NaN    0  20131203004552049   

                                                TXID  TXSZ UCPU  
0  NUAN-20131203004552049-FCJNJKDCAAANPCKEAAAAAAA...  1167   31  
1                                                NaN   NaN   31  
2                                                NaN   NaN    0  

[3 rows x 15 columns]

获得此功能后,您可以根据需要重新塑造。 (我不确定你是否想要将行与相同的时间和陈相结合。)


编辑:如果您使用的旧版本的pandas不支持将生成器传递给from_dict,则可以从列表中构建它:

df = pd.DataFrame(list(rows))

但请注意,您必须在事后将字符串转换为字符串中的数字列。