Python基于唯一值查找、匹配、排序和追加

2024-04-26 11:00:35 发布

您现在位置:Python中文网/ 问答频道 /正文

一个CSV文件有两个指定的帐户结构。 我的问题是,有一个双反向条目为这些链接的每一个。你知道吗

示例

Column1 Column2
12513   52188
52188   12513

另一个问题,我也有可能有更多的条目,其中指定另一个链接,从同一个帐号

Column1 Column2
12513   52188
52188   12513
52188   19922
19922   52188
19922   12812
12812   19922
18216   59888
59888   18216
3856   59888
59888   3856

正如您所看到的,所有帐户都以某种方式相互关联,我要查找的输出应该创建一个与从属帐户链接的主帐户(可能是值最低的帐户),并删除双反条目。你知道吗

上述数据输出示例:

Column1 Column2
12513   52188
12513   19922
12513   12812
3856    59888
3856    18216

该文件包含大约20000行, 请注意,并不是只有一个主帐户。你知道吗


Tags: 文件csv数据示例链接方式条目帐户
1条回答
网友
1楼 · 发布于 2024-04-26 11:00:35

所以问题是:
给定表单中的数据集

1,2
1,3
1,4
3,1
6,5
5,7

识别链1 -> 2 -> 3 -> 45 -> 6 -> 7 并输出为

1,2
1,3
1,4
5,6
5,7

这里有一个python的工作解决方案。(节日快乐)

要运行它,请使用python thisfile.py yourdata.csv > output.csv

当然,您需要安装python3。 代码中有很多注释。我根本没有考虑效率问题,所以把水壶放上——大约需要15分钟才能完成。

如果你想它更快,它是列表.append()需要时间的电话。使用numpy可能会加快速度,但我不想添加额外的依赖项。你知道吗

如果你有任何问题,请告诉我。你知道吗

示例数据的输出为:

3856 , 18216
3856 , 59888
12513 , 12812
12513 , 19922
12513 , 52188
import csv
import sys


def flatten(l):
    return list(set([item for subl in l for item in subl]))

def main():
    # read the csv                                                                                      
    raw_data = []
    with open(sys.argv[1], 'r') as so_data:
        lst = csv.reader(so_data)
        for row in lst:
            raw_data.append(row)

        data = []
        for i in raw_data:
            data.append([int(i[0].strip()), int(i[1].strip())])

        #set keys to uniq elements from col1 and col2                                                   
        keys1 = list(set([i[0] for i in data]))
        keys2 = list(set([i[1] for i in data]))
        keys = list(set(keys1 + keys2))

        # find the subchains for each key                                                               
        subchains = {}
        for key in keys:
            found = [k for k in data if key in k]
            found = flatten(found)
            subchains[key] = found

        # This is the tricky bit                                                                        
        # we need to follow each element of the subchains looking                                       
        # for new links - we are done for a key when the list doesn't grow                              
        chain, links = [], []
        chain_dict = {}
        for key in keys:
            links.append(subchains[key])
            links = flatten(links)
            done = False
            size = len(links)
            while not done:
                for i in links:
                    # find subchain for i                                                               
                    for e in subchains[i]:
                        chain.append(e)
                        chain = list(set(chain))
                        chain.sort()
                if len(chain) > size:
                    done = False
                    size = len(chain)
                else:
                    done = True
                    chain_dict[key] = chain
                    chain, links = [], []

        # shorter chains will now be subsets of longer ones                                             
        # and those can be discarded                                                                    
        remove_list = []
        for i in keys:
            for j in keys:
                if set(chain_dict[j]) < set(chain_dict[i]):
                    remove_list.append(j)

        remove_list = list(set(remove_list))
        for i in remove_list:
            del chain_dict[i]

        # remove duplicate values from dict                                                             
        # it doesn't matter which key we remove                                                         
        # since we only output from value                                                               
        result = {}
        for key, value in chain_dict.items():
            if value not in result.values():
                result[key] = value

        # now output as per OP's request                                                                
        for k, v in result.items():
            v.sort()
            for i in v[1:]:
                print(v[0], ",", i)

if __name__ == '__main__':
    main()

相关问题 更多 >