我有一个包含许多列的FITS文件。该文件的简化示例的一部分如下所示:
A B C
100 1 90
100 2 90
100 3 90
100 4 90
211 40 70
211 41 70
211 42 70
211 43 70
211 44 70
如果您在此处注意到, A和C 列的前四行是相同的,但 B 列从1到4不等。然后接下来的5个值列 A和C 相同,但 B 列从40到44不等。
我想做的是,编写一个创建如下文件的程序:
A B C
100 4 90
211 5 70
也就是说, B列应该包含A列和C列相同的值的数量!
我想知道在Python中如何做到这一点。它不一定需要处理FITS文件,如果有一些例程无法在FITS文件中使用,我也可以将其转换为ASCII格式。
到目前为止我尝试过:
我遇到了一个名为Collections
的例程,它有一个名为Counter
的子例程,它计算列表中相等的值并返回它们。
我试过了:
import collections
counter = collections.Counter(a)
counts = counter.values()
但这只会让我在 A 列中的值相等。有人可以告诉我如何使用此例程将这些值与列 C 进行比较吗?
答案 0 :(得分:5)
我会选择这样的东西......:
from itertools import groupby
from operator import itemgetter
with open('input') as fin, open('output', 'w') as fout:
fout.write(next(fin, ''))
rows = (line.split() for line in fin)
for k, g in groupby(rows, itemgetter(0, 2)):
fout.write('{} {} {}\n'.format(k[0], sum(1 for _ in g), k[1]))
itertools.groupby
分组第一列和第三列g
中出现的次数以获得组的长度如果论坛不连续且您应该计为一个,您也可以使用collections.Counter
,您可以使用以下内容替换groupby
:
counts = Counter((row[0], row[2]) for row in rows)
for k, v in counts.iteritems():
fout.write('{} {} {}\n'.format(k[0], v, k[1]) # or even...
# print >> fout, k[0], v, k[1]
答案 1 :(得分:3)
这似乎按预期工作:
out = [["A", "B", "C"]]
# Safely handle opening the file
with open("demo.txt") as f:
a_count = 1
prev_a = None
for i, line in enumerate(f):
a, b, c = [int(x) for x in line.split()]
if i != 0:
if prev_a == a and prev_c == c:
a_count += 1
else:
out.append([prev_a, a_count, prev_c])
a_count = 1
# Keep track of our last results
prev_a, prev_c = a, c
# Collect the final line counts
if prev_a:
out.append([prev_a, a_count, prev_c])
# Pretty-print our results
for line in out:
print "{0: ^6}{1: ^6}{2: ^6}".format(*line)
答案 2 :(得分:0)
您应该在问题中添加一些代码,以显示您尝试过的内容。如果他们看不到你的尝试,人们通常不会想要帮助很多 - 包括我自己。
作为逻辑方面的暗示(基本。有更简洁的方法):
尝试使用由A列和C列编号组成的密钥。然后,每当A和C相同时,在字典中搜索具有该组合的键,如果找到,则将值加1,如果找不到,则添加新元素。
使用你的例子(伪代码 - 所以你有事情要做:P)
if "100-90" in array: // Checking if the element is in the array
array["100-90"] += 1 // Adds one to an existing element
else
array["100-90] = 1 // Adds a new element into array
答案 3 :(得分:0)
试试这个:
lines = """100 1 90
100 2 90
100 3 90
100 4 90
211 40 70
211 41 70
211 42 70
211 43 70
211 44 70""".split("\n")
count = 0
oldA = oldB = oldC = None
for line in lines:
a,b,c = line.split(" ")
if None in [oldA, oldB, oldC]:
oldA,oldB,oldC = a,b,c
if oldA == a and oldC == c:
count +=1
else:
print oldA,count,oldC
count = 1
oldA, oldB, oldC = a,b,c
print oldA,count,oldC