python:groupby(合并)下一行与上一行,如果它们在文本数据中以相同的匹配模式开头
python: groupby (merge) next lines with previous line if they start with same match pattern in text data
我有一个 file.txt 数据组 (AAA-(n)) 非常大。文件中的许多行在文件中的 AAA -(n) 到 AAA-(n+1) 行之间具有相同的标记(例如 AB)。我想把它们排成一行。例如:
AAA-1
XX-a
AB-a
AB-b
AB-c
numb-a
lime-a
lime-b
XX-b
AB-d
AB-e
lime-c
AAA-2
.
.
AAA-n
.
.
我想要的输出是:
AAA-1
XX-a
AB-a;b;c
numb-a
lime-a;b
XX-b
AB-d;e
lime-c
AAA-2
.
.
.
AAA-n
.
.
我试过这个:
from itertools import groupby, count
counter = count()
with open('file.txt') as f:
for key, group in groupby(f, lambda s: next(counter) if s.startswith('AAA') or s.startswith('XX') else -1):
print(';'.join(s.rstrip('\n') for s in group))
输出:
AAA-1
XX-a
AB-a;AB-b;AB-c;numb-a;lime-a;lime-b
XX-b
AB-d;AB-e;lime-c
AAA-2
plz,帮我避免将其他标签与 AB 分组并在分组后删除标签?
编辑:已更新以获得正确的输出
这是我想出的:
df = pd.DataFrame.from_dict({'data': dat})
df['data'] = df['data'].str.split('-')
df['tag'] = [x[0] for x in df['data']]
df['tail'] = [x[1] for x in df['data']]
i = 0
while i < (len(df) - 1):
tails = [df.iat[i, 2]]
j = 1
while(df.iat[i, 1] == df.iat[i+j, 1]):
tails.append(df.iat[i+j, 2])
j += 1
df.loc[i, 'tails'] = tails
i += j
df.dropna(how='any', axis=0, inplace=True)
df.reset_index(drop=True, inplace=True)
df.drop(columns=['data', 'tail'], inplace=True)
df['final'] = [df.at[i, 'tag'] + '-' + ';'.join(df.at[i, 'tails']) for i in range(len(df))]
输出:
想到的第一个方法是将尾随字符从标记中拆分出来并放在单独的列中。假设您正在使用 Pandas 并且它已经在 DF 中:
df['data'] = df['data'].str.split('-')
df['tag'] = [x[0] for x in df['data']]
df['tail'] = [x[1] for x in df['data']]
所以现在您有一个包含原始数据的列、一个包含标签的列和一个包含尾部的列。
现在您可以按标签分组:
grouped = df.groupby('tag')
从这里您可以使用 lambda 函数实现您想要的:
out = grouped.agg({'tail': lambda t: ''.join(t)})
从这里您可以重置索引,用破折号连接成一个字符串,任何您想要的。
我有一个 file.txt 数据组 (AAA-(n)) 非常大。文件中的许多行在文件中的 AAA -(n) 到 AAA-(n+1) 行之间具有相同的标记(例如 AB)。我想把它们排成一行。例如:
AAA-1
XX-a
AB-a
AB-b
AB-c
numb-a
lime-a
lime-b
XX-b
AB-d
AB-e
lime-c
AAA-2
.
.
AAA-n
.
.
我想要的输出是:
AAA-1
XX-a
AB-a;b;c
numb-a
lime-a;b
XX-b
AB-d;e
lime-c
AAA-2
.
.
.
AAA-n
.
.
我试过这个:
from itertools import groupby, count
counter = count()
with open('file.txt') as f:
for key, group in groupby(f, lambda s: next(counter) if s.startswith('AAA') or s.startswith('XX') else -1):
print(';'.join(s.rstrip('\n') for s in group))
输出:
AAA-1
XX-a
AB-a;AB-b;AB-c;numb-a;lime-a;lime-b
XX-b
AB-d;AB-e;lime-c
AAA-2
plz,帮我避免将其他标签与 AB 分组并在分组后删除标签?
编辑:已更新以获得正确的输出
这是我想出的:
df = pd.DataFrame.from_dict({'data': dat})
df['data'] = df['data'].str.split('-')
df['tag'] = [x[0] for x in df['data']]
df['tail'] = [x[1] for x in df['data']]
i = 0
while i < (len(df) - 1):
tails = [df.iat[i, 2]]
j = 1
while(df.iat[i, 1] == df.iat[i+j, 1]):
tails.append(df.iat[i+j, 2])
j += 1
df.loc[i, 'tails'] = tails
i += j
df.dropna(how='any', axis=0, inplace=True)
df.reset_index(drop=True, inplace=True)
df.drop(columns=['data', 'tail'], inplace=True)
df['final'] = [df.at[i, 'tag'] + '-' + ';'.join(df.at[i, 'tails']) for i in range(len(df))]
输出:
想到的第一个方法是将尾随字符从标记中拆分出来并放在单独的列中。假设您正在使用 Pandas 并且它已经在 DF 中:
df['data'] = df['data'].str.split('-')
df['tag'] = [x[0] for x in df['data']]
df['tail'] = [x[1] for x in df['data']]
所以现在您有一个包含原始数据的列、一个包含标签的列和一个包含尾部的列。
现在您可以按标签分组:
grouped = df.groupby('tag')
从这里您可以使用 lambda 函数实现您想要的:
out = grouped.agg({'tail': lambda t: ''.join(t)})
从这里您可以重置索引,用破折号连接成一个字符串,任何您想要的。