【问题标题】:Loop through .csv files with conditions in different columns循环遍历具有不同列中条件的 .csv 文件
【发布时间】:2014-05-16 19:43:56
【问题描述】:

我有一个采用这种格式的大型 .csv 文件:

“字符串 1”、“字符串 2”、“字符串 3”、“字符串 4”、“字符串 5”、“字符串 6”等

我有兴趣从列中提取信息,只要它链接到以下列。

举一个更清楚的例子,假设第 3 列和第 4 列由团队组成,它们代表他们主办的人(第 3 列是本地团队)。

“第一”、“结果”、“费城”、“迈阿密”等
“第二”、“结果”、“达拉斯”、“克利夫兰”等
“第三”、“结果”、“迈阿密”、“克利夫兰”等
“第四”、“结果”、“克利夫兰”、“迈阿密”等
《第五》、《结果》、《达拉斯》、《费城》等
“第六”、“结果”、“克利夫兰”、“达拉斯”等
《第七》、《结果》、《迈阿密》、《费城》等
《第八》、《结果》、《费城》、《迈阿密》等
“第九”、“结果”、“克利夫兰”、“迈阿密”等

我想获得一份由他们主办的团队组成的列表,无需重复

Cleveland hosts
Dallas
Miami

Dallas hosts
Cleveland
Philadelphia

Miami hosts
Cleveland
Philadelphia

Philadelphia hosts
Miami

之后,我想在一个文件中写入有关这两种模式的所有行,也就是说,如果我想查看克利夫兰和迈阿密之间的匹配,我希望有一个这样的 .csv,

“第三”、“结果”、“迈阿密”、“克利夫兰”等
“第四”、“结果”、“克利夫兰”、“迈阿密”等
“第九”、“结果”、“克利夫兰”、“迈阿密”等

使用以下代码,我设法读取一列并将所有唯一元素存储在字典中,以便以后可以从中选择一个单词。我可以对第 4 列执行相同的操作,并通过将参数 Wanted_Column 的值更改为 3 来重复代码

import csv
from collections import Counter, defaultdict, OrderedDict

Var = 1 
Wanted_Column = 2 # Col I want to analyze 

with open('file.csv', "rb") as inputfile:
    data = csv.reader(inputfile)
    seen = defaultdict(set)

    countd = Counter(
        row[Wanted_Column]
        for row in data
        if row[Wanted_Column] and row[Wanted_Column] not in seen[row[Var]] and not seen[row[Var]].add(row[Wanted_Column])
    )

y = OrderedDict(sorted(countd.items(), key = lambda t: t[0]))

for line in y:
    print line

结果是,

Cleveland
Dallas
Miami 
Philadelphia 

所以,我的问题是,我应该添加什么来获得双重条件并以我暴露的方式显示元素?

之后,要在另一个文件中写入行,我有这段代码,

look_for = set([ELEMENT IN DICTIONARY])

with open('file.csv','rb') as inf, open('output_file.csv','wb') as outf:
    incsv = csv.reader(inf, delimiter=',')
    outcsv = csv.writer(outf, delimiter=',')

    outcsv.writerows(row for row in incsv if row[Wanted_column] in look_for) 

而且只有一个元素就可以很好地工作,但是当然,由于前面的条件没有很好地定义,我不知道我应该改变什么才能得到我想要的结果。

【问题讨论】:

    标签: python loops csv dictionary


    【解决方案1】:

    你能用一个集合字典吗?

     f = open('test.csv')
    hosts = {}
    
    #read
    for line in f:
        line = line.replace('"', '')
        res = line.split(',')
    
        if not hosts.get(res[2]):
            hosts[res[2]] = set([])
    
        hosts.get(res[2]).add(res[3])
    
    #print
    for key in sorted(hosts.keys()):
        print 'HOST', key
        for guest in sorted(list(hosts[key])):
            print 'GUEST', guest
    
    print hosts
    

    那么最终的打印将只是循环通过 hosts 键并打印集合的内容。

    如果事先不知道列数,但你知道它是host, guest,那么它只是一个从位置 2 开始遍历整行的内部循环的问题。

    添加了最后一行以显示排序打印。此脚本中的输入与您的输入之间的唯一区别是我删除了 .etc 列并假设输入停止在那里。扩展它应该是微不足道的

    【讨论】:

    • 谢谢。其实我没有想到,我会看看的。从我的最后一段代码,写作部分,我需要在最后一行更改什么?
    • 看上面的例子。它也会为您进行排序打印。只需修改您的脚本以遵循我的模式。
    • 只需将print 语句更改为使用您的格式规则写入文件
    【解决方案2】:

    您可以使用集合字典来跟踪主办团队和独特的访问团队。这是一个例子。

    import csv
    
    # load the csv file
    rows = [r for r in csv.reader(file('sample.csv','r'))]
    
    # order preservation list
    preserve_order = []
    
    # track the schedule from the hosting team's point of view
    hosting_teams = {}
    
    # change the wanted column here
    wanted_column = 3
    
    for row in rows:
        # strip out the double quotes
        row = [c.replace('"','') for c in row] 
    
        the_host = row[2]
        the_order = row[0]
    
        preserve_order.append(the_order)
    
        # create a dictionary with a unique set of visiting teams
        host_schedule = hosting_teams.setdefault(the_host,set([]))
    
        # add the team visit
        visiting_team = row[wanted_column]
        host_schedule.add((visiting_team,the_order))
    
    
    
    output = []
    for hosting_team,host_schedule in hosting_teams.items():
        for visiting_team,the_order in host_schedule:
            output.append([the_order,"Result",hosting_team,visiting_team])    
    
    output.sort(key=lambda x:preserve_order.index(x[0]))
    
    csv.writer(file('output.csv','wb')).writerows(output)    
    

    【讨论】:

    • 感谢您的帮助,问题是如果我这样做,.csv 是全局的(所有匹配项都会出现)并且是随机排序的,也就是说,第 9 场比赛可以出现在第 4 场比赛之前,尽管两者都有曾在克利夫兰踢过,迈阿密是接球队,我还将看到费城和达拉斯的比赛。如果我没记错的话,您的代码将编写一个 .csv,其中所有行都由第二列收集。它有效,但并不能真正解决我的问题。首先,我如何使用 OrderedDict 和两个按第一个排序的参数,第二,我如何只将一个“双重模式”写入 .csv?
    猜你喜欢
    • 2014-04-10
    • 1970-01-01
    • 2018-02-07
    • 2017-10-02
    • 1970-01-01
    • 2019-04-11
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    相关资源
    最近更新 更多