python用newline将文件分为块



i有一个文件,该文件被newline分隔为相同数量的行的块。每一行都是一个字段。例如,在Chunk1中,第一个字段= A1,A2,A3。在chunk2中,相同的字段= a2,a3,a4。

a1,a2,a3
b1
c1,c2,c3,c4
d1
e1
a2,a3,a4
b2
c3,c4
d2
e2
a3,a5
b3
c4,c6
d3
e3

如何获得如下的dataframe(或其他数据结构(?

    f1        f2       f3            f4  f5 
    a1,a2,a3  b1       c1,c2,c3,c4   d1  e1
    a2,a3,a4  b2       c3,c4         d2  e2
    a3,a5     b3       c4,c6         d3  e3

谢谢!

打开文件是行的迭代器。您想要一组线的迭代器。

由于所有这些组都长6行(在末端计算空白行(,因此最简单的方法是使用文档中的itertools配方中的grouper示例。(如果您愿意,您还可以从PYPI上的more-itertools库中获得预制版本。(

from itertools import *
def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)
with open(path) as f:
    for group in grouper(f, 6):
        do_something(group)

如果您的组的长度不预先知道(即使在文件中始终是一致的(,则可以使用groupby来创建空的和非空线的交替组。这有点像在字符串上使用split

我们可以在这里只使用bool作为关键函数 - 非空线是真实的,一个空行是假的。(如果对您来说似乎很奇怪,则可以写lambda line: linelambda line: line != ''之类的东西。(

with open(path) as f:
    for nonempty, group in groupby(f, bool):
        if nonempty:
            do_something(group)

或者,如果这似乎超过了您的脑海……好吧,先阅读David Beazley为系统程序员的发电机技巧,也许它不会再浮出水面了。但是,如果是,我们可以更明确地做同样的事情:

with open(path) as f:
    group = []
    for line in f:
        if line:
            group.append(line)
        else:
            do_something(group)
            group = []
    if group:
        do_something(group)

如果您可以使用熊猫并知道有多少个字段:

fields = 5
df = pd.read_table('data.txt', header=None)
df = pd.DataFrame(df.values.reshape(-1, fields)))

如果不知道多少个字段:

df = (pd
      .read_table('data.txt', header=None, skip_blank_lines=False)
      .append([np.nan]))
# empty lines become NaN. Find the first of them.
fields = np.where(pd.isnull(f))[0][0]
df = pd.DataFrame(df.values.reshape(-1, fields + 1)))
del df[df.columns[-1]]  # delete the NaN column

您可以尝试生成器方法:

def chunks_by_space(file):
    with open(file,'r') as f:
        data=[line.strip() for line in f.readlines()]
        store=[]
        for line_no,value in enumerate(data):
            if value=='':
                yield store
                store=[]
            else:
                store.append(value)
        yield store
gen=chunks_by_space('file_name')
print(list(zip(*gen)))

输出:

[('a1,a2,a3', 'a2,a3,a4', 'a3,a5'), ('b1', 'b2', 'b3'), ('c1,c2,c3,c4', 'c3,c4', 'c4,c6'), ('d1', 'd2', 'd3'), ('e1', 'e2', 'e3')]

最新更新