Python 向选项卡式行添加唯一标签

Python 向选项卡式行添加唯一标签,python,pandas,csv,dataframe,Python,Pandas,Csv,Dataframe,我有一个文本文件,其中一些行在一个选项卡上移动,表示它们是主行的子类别。我需要用一个唯一的标签标记每一行,表明它们属于哪个“组”或类别,以便对每个类别进行统计分析 我不太确定如何在Python中实现自动化,因为文件中有数千行。我无法将文件转换为csv而不首先转换所有缩进的行,这显然会失去辨别每行属于哪个类别的能力 编辑: 前3行将具有组标签“1”,下2行将具有标签“2”,最后2行将分别具有标签“3”和“4” 这不是最好的方法,但应该有效。首先,您需要接收文件中的所有数据。只需打开文件,逐行读取

我有一个文本文件,其中一些行在一个选项卡上移动,表示它们是主行的子类别。我需要用一个唯一的标签标记每一行,表明它们属于哪个“组”或类别,以便对每个类别进行统计分析

我不太确定如何在Python中实现自动化,因为文件中有数千行。我无法将文件转换为csv而不首先转换所有缩进的行,这显然会失去辨别每行属于哪个类别的能力

编辑:


前3行将具有组标签“1”,下2行将具有标签“2”,最后2行将分别具有标签“3”和“4”

这不是最好的方法,但应该有效。首先,您需要接收文件中的所有数据。只需打开文件,逐行读取所有数据到名为数据的字符串:

with open("your_text_file.txt", "r") as f:
    data = f.read().split('\n')
为了模拟您的文件,我假装所有数据都已存储在数据变量中:

data = """ratio, weight, flags, initialTime, finalTime
15,    0.44,    3,    300500,    400000
    42,    0.31,   2,   900432,   100304
22,    1.31,   3,   200432,   100304
    52,    0.11,   4,   922432,   111304 """
group = 0
data = data.split('\n')
#insert name group in firts line of your data
data[0] = f"group, {data[0]}"
for count,items in enumerate(data[1:]):
    #if line do not start with tab increment group number by 1
    if not items.startswith("    "):
        group += 1
    #insert first raw as group
    items = f"{group}, {items}"
    #deleta all ugly tabs
    items = ' '.join(items.split())
    #rewrite dataline with new beatiful string
    data[count+1] = items
#now create csv file with beautiful data
with open("new_file.csv", "w") as f:
    for items in data:
        f.write(f"{items}\n")
因此,我的第一个数据如下所示:

ratio, weight, flags, initialTime, finalTime
15,    0.44,    3,    300500,    400000
    42,    0.31,   2,   900432,   100304
22,    1.31,   3,   200432,   100304
    52,    0.11,   4,   922432,   111304 
group, ratio, weight, flags, initialTime, finalTime
1, 15, 0.44, 3, 300500, 400000
1, 42, 0.31, 2, 900432, 100304
2, 22, 1.31, 3, 200432, 100304
2, 52, 0.11, 4, 922432, 111304
在像这样运行脚本之后:

ratio, weight, flags, initialTime, finalTime
15,    0.44,    3,    300500,    400000
    42,    0.31,   2,   900432,   100304
22,    1.31,   3,   200432,   100304
    52,    0.11,   4,   922432,   111304 
group, ratio, weight, flags, initialTime, finalTime
1, 15, 0.44, 3, 300500, 400000
1, 42, 0.31, 2, 900432, 100304
2, 22, 1.31, 3, 200432, 100304
2, 52, 0.11, 4, 922432, 111304

希望,这就是您需要的

IIUC,这里有一个使用Pandas和
itertools.chain的相对简单的方法

import pandas as pd
import numpy as np
import io, re, itertools

data = '''
ratio,  weight, flags,  initialTime,    finalTime
15,     0.44,   3,      300500,         400000
        42,     .31,    2,      900432,         100304
        41,     .2,     7,      192834,         200048
17,     0.234,  2,      2019481,        2182350
        8,      .1,     9,      1092834,        1190924
8,      0.241,  2,      2115120,        2159009
10,     0.092,  9,      2011234,        5001234
'''

data = re.sub(r'\t+', '*', data)
df = pd.read_csv(io.StringIO(data))

df.columns = [i.strip('*') for i in df.columns]
df.loc[df['ratio'].str.contains(r'\*'), 'ratio'] = np.nan
df['ratio'] = df['ratio'].ffill()
group_numbers = itertools.chain.from_iterable([[i+1]*v.shape[0] for i, (name,v) in enumerate(df.groupby('ratio', sort=False))])
df['ratio'] = list(group_numbers)
df = df.replace(r'\*', '', regex=True).set_index('ratio')
收益率:

      weight  flags initialTime finalTime
ratio                                    
1       0.44      3      300500    400000
1        .31      2      900432    100304
1         .2      7      192834    200048
2      0.234      2     2019481   2182350
2         .1      9     1092834   1190924
3      0.241      2     2115120   2159009
4      0.092      9     2011234   5001234

如果要构建数据帧,可以使用numpy
genfromtext
和生成器添加新字段

def add_group(fd):
    """generator that prepends each line with a group field (returns byte strings)"""
    digit = re.compile(r'^\d')
    line = next(fd)                     # process header line
    yield('group,'+line).encode()
    group=0
    for line in fd:
        if digit.match(line):           # increment group when first char is a digit
            group += 1
        yield "{},{}".format(group, line).encode()

df = pd.DataFrame(np.genfromtxt(add_group(open('file.txt')), delimiter=',', names=True,
                  autostrip=True, dtype=None)
如果您只想构建csv,则更简单:

with open('file.txt') as fd, open('file.csv', 'w') as fdout):
    digit = re.compile(r'^\d')
    fdout.write('group,'+next(fd))     # process header line
    group = 0
    for line in fd:
        if digit.match(line):           # increment group when first char is a digit
            group += 1
        fdout.write("{},{}".format(group, line).encode())

你能在你的帖子中加入这个文本文件的一个小样本吗?当然,刚刚添加。