使用python

时间:2017-09-15 10:11:20

标签: python pandas text-processing

我正在尝试找出一种方法,使用python 3.5将.txt文件理想地导入为dataframe(pandas)。我用不同的数据做了几次。这个文件有几千个案例/实例,每个13行后跟一个空行:

Cat1: text
…
Cat13: text

Cat1: text
…
Cat13: text …

使用以下代码,我可以访问每一行并为每个实例创建一个新的向量(不幸的是作为列向量而不是行向量,可以将其添加到新数据框中):

import codecs
import pandas as pd
with codecs.open(‚file.txt', 'r',encoding='utf-8', errors='ignore') as f:
    lines = f.readlines()

L = list(lines[i] for i in range(14))
se = pd.Series(L[:13])
df = pd.DataFrame([], columns=('Cat1’,…,’Cat13‘))
df['new_row'] = se.values

我正在寻找一个基本数据框(实例x 13),其中'Cat1',...,'Cat13'作为列,实例作为行。

Cat1  Cat2 ... Cat13
text  text     text
text  text     text
...

是否可以轻松解决此问题,甚至是另一个加载此类文件的程序包?

修改 真的不确定我在寻找什么。最后,我们可以使用itertools.groupby中提到的this thread来解决此问题。

import itertools
import codecs
import pandas as pd

def group_separator(line):
    return line=='\n'

with codecs.open('file.txt', 'r',encoding='utf-8', errors='ignore') as f:
    lines = f.readlines()

cols = ('Cat1',...,'Cat13')
data = []
for (key, group) in itertools.groupby(lines, group_separator):
    if key:
        next(group).strip()
    else:
        tem_data = [i.strip() for i in group]
        tem_data = filter(lambda l: l != '', tem_data)
        tem_data = [i.split(':',1) for i in tem_data]
        tem_data = [i[1].strip() for i in tem_data]
        if len(tem_data) == 13:
            data.append(tem_data)

df = pd.DataFrame(data, columns=cols)

1 个答案:

答案 0 :(得分:0)

给定输入文件的格式:

Cat1/instance1: text …
Cat13/instance1: text

Cat1/instance2: text …
Cat13/instance2: text …

您可以将文件读取为一列数据框,如下所示(ps:pandas将自动跳过空行):

In [70]: df = pd.read_csv('/tmp/test.txt', header=None)

In [71]: df
Out[71]: 
                         0
0   Cat1/instance1: text …
1    Cat13/instance1: text
2   Cat1/instance2: text …
3  Cat13/instance2: text …

In [72]: 

根据/:拆分行以构建包含三列的新数据框:

In [72]: dff = pd.DataFrame(df[0].str.strip().str.split('/|: ').tolist())

In [73]: dff
Out[73]: 
       0          1       2
0   Cat1  instance1  text …
1  Cat13  instance1    text
2   Cat1  instance2  text …
3  Cat13  instance2  text …

In [74]: 

然后将前两列[0, 1]设置为dff的索引,使用索引的第一级将数据帧取消堆叠,以使cat1..cat13成为新列。然后使用reset_index删除instance1.. instance2一行:

In [74]: dff = dff.set_index([0,1]).unstack(level=0).reset_index(drop=True)

In [75]: dff
Out[75]: 
        2        
0    Cat1   Cat13
0  text …    text
1  text …  text …

In [76]: 

最后,我们需要删除列中的uncessary级别并仅保留cat1... cat13

In [76]: dff.columns = dff.columns.levels[1].tolist()

In [77]: dff
Out[77]: 
     Cat1   Cat13
0  text …    text
1  text …  text …

In [78]: 

如果没有上述解释,整体代码如下所示:

df = pd.read_csv('/tmp/test.txt', header=None)
dff = pd.DataFrame(df[0].str.strip().str.split('/|: ').tolist())
dff = dff.set_index([0,1]).unstack(level=0).reset_index(drop=True)
dff.columns = dff.columns.levels[1].tolist() 

如果您想处理编码utf-8,请按以下步骤阅读该文件:

df = pd.read_csv('/tmp/test.txt', header=None, encoding='utf-8')