计算两个表中等效行的交集数量

4 投票
5 回答
1233 浏览
提问于 2025-04-18 18:04

我有两个FITS文件。我们假设第一个文件有100行和2列,第二个文件有1000行和2列。

    FITS FILE 1      FITS FILE 2

    A        B        C        D
    1        2        1        2
    1        3        1        2  
    2        4        1        2

我需要拿第一个文件的第一行,也就是1和2,然后检查第二个文件中有多少行包含1和2。在我们的例子中,第二个文件中有3行包含1和2。我还需要对第二行(第一个文件)做同样的事情,也就是1和3,找出第二个文件中有多少行包含1和3,依此类推。

第一个文件没有重复的行(所有的行都是不同的组合,没有完全相同的,只有第二个文件有很多相同的组合,我需要找出来)。

最后,我需要知道第二个文件中有多少行的值和第一个FITS文件的行相似。

所以最后的结果将是:

A    B    Number
1    2      3   # 1 and 2 occurs 3 times
1    3      5   # 1 and 3 occurs 5 times

依此类推。

我知道我需要遍历这个列表来得到答案。我知道zip可以让我获取第一个文件的行,但我找不到用这些值遍历的方法。

到目前为止,我尝试用zip来实现这个目标:

for i,j in zip(A,B):
    for m,n in zip(C,D):

通过使用for i,j in zip(A,B):我可以得到i,j是第一个文件的第一行,依此类推。这样我就可以和第二个文件进行比较。

5 个回答

-1
def read_from_file(filename):
    with open(filename, 'r') as f:
        data = f.read()
    return data


def parse_data(data):
    parsed_data = []
    for line in data.split('\n'):
        line_striped = line.strip()  # remove spaces on left and right site
        try:
            left, right = line_striped.split(' ', 1)  # split on first space
        except ValueError:
            continue
        right = right.strip()  # remove spaces on left site from right
        parsed_data.append((left, right))
    return parsed_data


f1_data = read_from_file("file1.txt")
f2_data = read_from_file("file2.txt")
f1_pdata = parse_data(f1_data)
f2_pdata = parse_data(f2_data)

# compare
for f2_item in f2_pdata:
    for f1_item in f1_pdata:
        if f2_item == f1_item:
            print f2_item, "occures in file2 and file1"

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

0

这可能会对你有帮助。看看评论部分可以更好地理解。

import numpy as np
from collections import Counter

A = np.array([1,1,2,4])
B = np.array([2,3,4,5])

C = np.array([1,1,1,1,2,1,1])
D = np.array([2,2,2,3,4,4,3])

dict1 = Counter(zip(C,D)) # made a dictionary of occurrences of results of zipping C an D 

#print dict1 #just uncomment this line to understand what Counter do.
print("A    B : Rowcount")
for i in zip(A,B):
    print (str(i[0]) + "    " + str(i[1]) + " : " + str(dict1[i]))

输出结果:

A    B : Rowcount
1    2 : 3
1    3 : 2
2    4 : 1
4    5 : 0
0

1. 把文件1的每一行都加载到一个字典里,每一行作为一个键,值都设为0。

2. 遍历文件2,如果某一行在之前的字典中找到了对应的键,就把这个键的值加1。

3. 显示字典的结果。

0

Pandas可能对这种情况很有帮助。这个例子是从头开始构建两个Pandas的DataFrame,不过你也可以把FITS表格放进DataFrame里(我觉得那是个单独的问题)。接下来用你帖子里的例子:


>>> import pandas
>>> table1 = pandas.DataFrame({'A': [1, 1, 2], 'B': [2, 3, 4]})
>>> table2 = pandas.DataFrame({'C': [1, 1, 1], 'D': [2, 2, 2]})
>>> table1
   A  B
0  1  2
1  1  3
2  2  4
>>> table2
   C  D
0  1  2
1  1  2
2  1  2

现在有几种方法可以解决这个问题。其实,问题的表述有点模糊。你是想要表2中所有与表1匹配的行吗?还是说可以不考虑表2中的重复项?你可以这样做:


>>> m = pandas.merge(table1, table2, left_on=('A', 'B'), right_on=('C', 'D'), how='inner')
>>> m
   A  B  C  D
0  1  2  1  2
1  1  2  1  2
2  1  2  1  2
>>> m.drop_duplicates()
   A  B  C  D
0  1  2  1  2

基本上,这样做会给你两个表中所有相同的行。

4

你已经快完成了。你只需要一个 Counter 来统计第二个文件中每一行出现的次数。

from collections import Counter
# Create frequency table of (C,D) column pairs
file2freq = Counter(zip(C,D))
# Look up frequency value for each row of file 1
for a,b in zip(A,B):
    # and print out the row and frequency data.
    print a,b,file2freq[a,b]

就这样!只需要四行非常简单的代码。

如果你没有 collections.Counter,你可以用 defaultdict 来模拟它:

from collections import defaultdict
file2freq = defaultdict(int)
for c,d in zip(C,D):
    file2freq[c,d] += 1
for a,b in zip(A,B):
    print a,b,file2freq[a,b]

撰写回答