我有一个 .txt,例如(标签分隔):
1 2345
1 2346
1 2347
1 2348
1 2412
1 2413
1 2414
前四行连续包含从 2345 到 2348 的连续整数值。类似地,最后三行包含从 2412 到 2414 的连续值。我想对它们进行分组,使这些连续值集的最小值和最大值出现在一行上如下所示:
1 2345 2348
1 2412 2414
任何想法?
我有一个 .txt,例如(标签分隔):
1 2345
1 2346
1 2347
1 2348
1 2412
1 2413
1 2414
前四行连续包含从 2345 到 2348 的连续整数值。类似地,最后三行包含从 2412 到 2414 的连续值。我想对它们进行分组,使这些连续值集的最小值和最大值出现在一行上如下所示:
1 2345 2348
1 2412 2414
任何想法?
为此,您可以使用稍微修改过的Raymond Hettinger 集群函数版本:
def cluster(data, maxgap):
"""Arrange data into groups where successive elements
differ by no more than *maxgap*
>>> cluster([1, 6, 9, 100, 102, 105, 109, 134, 139], maxgap=10)
[[1, 6, 9], [100, 102, 105, 109], [134, 139]]
>>> cluster([1, 6, 9, 99, 100, 102, 105, 134, 139, 141], maxgap=10)
[[1, 6, 9], [99, 100, 102, 105], [134, 139, 141]]
https://stackoverflow.com/a/14783998/190597 (Raymond Hettinger)
"""
groups = [[data[0]]]
for x in data[1:]:
if abs(x - groups[-1][-1]) <= maxgap:
groups[-1].append(x)
else:
groups.append([x])
return groups
data = []
with open('data.txt', 'r') as f:
for line in f:
_, num = line.split()
data.append(int(num))
for row in cluster(data, 1):
print('1 {s} {e}'.format(s=row[0], e=row[-1]))
产量
1 2345 2348
1 2412 2414
使用模块读取和写入数据csv
,并跟踪“下一个”组何时开始:
import csv
def grouped(reader):
start = end = next(reader)
print start, end
for row in reader:
if int(row[1]) - 1 != int(end[1]):
yield (start, end)
start = end = row
else:
end = row
yield (start, end)
with open('inputfile.csv', 'rb') as inf, open('outputfile.csv', 'wb') as outf:
inputcsv = csv.reader(inf, delimiter='\t')
outputcsv = csv.writer(outf, delimiter='\t')
for start, stop in grouped(inputcsv):
outputcsv.writerow(start + stop[1:])
这写道:
1 2345 2348
1 2412 2414
供outputfile.csv
您输入。
这个解决方案永远不会在内存中保留超过 3 行的数据,因此您应该能够向其抛出任何大小的 CSV 文件。
numpy 提供了一些可以提供帮助的工具:
In [90]: import numpy as np
In [91]: x = np.loadtxt('seq.dat', dtype=int)
In [92]: x
Out[92]:
array([[ 1, 2345],
[ 1, 2346],
[ 1, 2347],
[ 1, 2348],
[ 1, 2412],
[ 1, 2413],
[ 1, 2414],
[ 1, 2500],
[ 1, 2501],
[ 1, 2502],
[ 2, 3000],
[ 2, 3001],
[ 2, 3100],
[ 2, 3101],
[ 2, 3102],
[ 2, 3103]])
In [93]: skip = np.where(np.diff(x[:,1]) != 1)[0]
In [94]: istart = np.hstack((0, skip + 1))
In [95]: istop = np.hstack((skip, -1))
In [96]: groups = np.hstack((x[istart], x[istop, 1:]))
In [97]: groups
Out[97]:
array([[ 1, 2345, 2348],
[ 1, 2412, 2414],
[ 1, 2500, 2502],
[ 2, 3000, 3001],
[ 2, 3100, 3103]])
分组时忽略第一列数据,因此如果第一列会影响组的形成方式,则需要进行一些调整。