Python 在FITS文件中按多列中的值聚合表行
我有一个包含许多列的FITS文件。该文件简化示例的一部分如下所示:Python 在FITS文件中按多列中的值聚合表行,python,fits,pyfits,Python,Fits,Pyfits,我有一个包含许多列的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 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和列的前四行是相同的,但是列B从1到4不等。然后,A列和C列的下5个值相同,但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进行比较吗?您应该在问题中添加一些代码,以显示您已经尝试过的内容。如果人们看不到你(包括我在内)的努力,他们通常不会愿意提供太多帮助 作为逻辑方面的提示(基本。有更简洁的方法): 试着用一本由a列和C列的数字组成的字典。然后,每当A和C相同时,在字典中搜索具有该组合的键,如果找到,则在值中添加1,如果未找到,则添加新元素 使用您的示例(在伪代码中-因此您有一些事情要做:p)
你应该在你的问题中添加一些代码,以显示你已经尝试了什么。如果人们看不到你(包括我在内)的努力,他们通常不会愿意提供太多帮助 作为逻辑方面的提示(基本。有更简洁的方法): 试着用一本由a列和C列的数字组成的字典。然后,每当A和C相同时,在字典中搜索具有该组合的键,如果找到,则在值中添加1,如果未找到,则添加新元素 使用您的示例(在伪代码中-因此您有一些事情要做:p) 试试这个:
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
试试这个:
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
这似乎起到了预期的作用:
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)
这似乎起到了预期的作用:
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)
我喜欢这样的东西…:
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
- 写出所需格式的行
集合。计数器
如果组是非连续的,并且应计为一个,则可以使用以下内容替换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]
我喜欢这样的东西…:
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
- 写出所需格式的行
集合。计数器
如果组是非连续的,并且应计为一个,则可以使用以下内容替换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]
你试过什么?你的初始代码是什么?什么不起作用?所以不是来做作业的,你应该先自己尝试:)@favoretti这不是作业!!我尝试过使用enumerate,但没有用。我也尝试过使用for循环进行思考,但没有任何帮助either@favoretti由于A和C不相等,即e没有相同的值,我很困惑该使用什么。如果它们相等,我可以使用enumerate并说如果A==C,返回len(B)@Srivatsan告诉我们你已经尝试过了,也许你已经接近了。@BartFriederichs我刚刚碰到了一个名为collections的包。我可以使用该包中的计数器只计算一列的值吗?在我的情况下,比如A?您尝试了什么?你的初始代码是什么?什么不起作用?所以不是来做作业的,你应该先自己尝试:)@favoretti这不是作业!!我尝试过使用enumerate,但没有用。我也尝试过使用for循环进行思考,但没有任何帮助either@favoretti由于A和C不相等,即e没有相同的值,我很困惑该使用什么。如果它们相等,我可以使用enumerate并说如果A==C,返回len(B)@Srivatsan告诉我们你已经尝试过了,也许你已经接近了。@BartFriederichs我刚刚碰到了一个名为collections的包。我可以使用该包中的计数器只计算一列的值吗?在我的例子中是A?问题是,我的文件有600多万行!!所以我正在搜索一个包,我刚才碰到了一个名为collections的包,它有一个子例程,名为counter,我正在尝试使用它now@Srivatsan是否需要为每个
a,c
组合存储x=len(b)
?是的,我需要所有a和c的值相等。i、 e镜头(b)@Srivatsan正常。1问题。您对此输入有何期望100 1 90\n 100 2 91\n 100 3 90\n 100 4 90\n 211 40 70\n 211 41 71\n 211 42 70\n 211 43 70\n 211 44 70\n问题是,我的文件有600多万行!!所以我正在搜索一个包,我刚才碰到了一个名为collections的包,它有一个子例程,名为counter,我正在尝试使用它now@Srivatsan是否需要为每个a,c
组合存储x=len(b)
?是的,我需要所有a和c的值相等。