编辑脚本以考虑两个列表的每个组合

时间:2013-11-11 22:24:19

标签: python python-2.7 csv collections defaultdict

所以,我认为这是一个难以解决的问题,我有一个循环通过CSV来计算不同列中数据出现次数的脚本。此脚本运行良好,包含在下面,用于引用:

原始脚本

import csv
import datetime
import copy
from collections import defaultdict

with open(r"C:\Temp\test2.csv") as i, open(r"C:\Temp\results2.csv", "wb") as o:
    rdr = csv.reader(i)
    wrt = csv.writer(o)

    data, currdate = defaultdict(lambda:[0, 0, 0, 0]), None
    for line in rdr:
        date = datetime.datetime.strptime(line[0], '%d/%m/%Y')

        name = (line[7], line[9])

        if date != currdate or not currdate:
            for v in data.itervalues(): v[:2] = v[2:]
            currdate = date

        wrt.writerow(line + data[name][:2])

        data[name][3] += 1
        if line[6] == "1": data[name][2] += 1

我已编辑此脚本以添加百分比列,我可以使此脚本手动执行多个不同的列匹配组合,例如第7/9列,我可以在一个脚本中将其作为第7/10行等。然而,我需要它做什么我不知道所需的功能或方法。基本上我需要它来遍历此脚本中包含的每个calclist,并为calclists中的每个列引用组合输出与此脚本关联的数字。即6/7 6/19 6/23

因为在我的真实脚本中,calc列表比这个例子长得多,如果这个编辑可能包含一些将标题附加到列的方法也很好我没有合适的方法或机制来执行此操作。但是如果有一个calc列表的标题列表,那么可以用这种格式创建一个标题(记住每次运行脚本有三个)"title1-title2-x","title1-title2-y","title1-title2-z"

import csv
import datetime
import copy
from collections import defaultdict

with open(r"dualparametermatch_test.csv") as i, open(r"dualparametermatch_test_edit.csv", "wb") as o:
    rdr = csv.reader(i)
    wrt = csv.writer(o)

    data, currdate = defaultdict(lambda:[0, 0, 0, 0]), None

    # Identical calclists
    calclist = [6, 7, 19, 23, 25, 26, 35, 62, 64]
    calclist2 = [6, 7, 19, 23, 25, 26, 35, 62, 64]

    for counter, line in enumerate(rdr):
        if counter == 0:
            #Titles, there are three for each item in the calclist
            titles = ["titleX", "titleY", "titleZ"] # ... etc
            wrt.writerow(line + titles)
        else:
            extra_cols = []
            for calc in calclist:
                date = datetime.datetime.strptime(line[0], '%d/%m/%Y')
                name = (line[calclist], line[calclist2])

                if date != currdate or not currdate:
                    for v in data.itervalues(): v[:2] = v[2:]
                    currdate = date

                 ### Adds the percentage calulation column
                top,bottom = data[name][0:2]
                try:
                    quotient = '{0:0.5f}'.format(float(top)/bottom).rstrip("0")
                except ZeroDivisionError:
                    quotient = 0
                extra_cols.extend(data[name][:2]+ [quotient])

                data[name][3] += 1
                if line[6] == "1": data[name][2] += 1

            wrt.writerow(line + data[name][:2])

我很欣赏这可能是一个难以解决的问题,如果有人可以帮助解决这个问题,那么首先要向你致敬!如果需要更多详细信息或任何不清楚的地方,请回复我。如果需要,我可以为原始脚本提供示例数据和输出。在此先感谢AEA

2 个答案:

答案 0 :(得分:1)

我不确定我是否正确理解了这个问题,所以这可能完全偏离基础,但如果您只想要所有卡座中出现的数字的所有独特组合,您可以像这样接近它:

calclists = [[1,2,3], [4,5,6], [7,8,9]] # calclists is a list of calclists
calcset = set()
for calclist in calclists:
    for x in calclist:
        calcset.add(x)
unique_calclist = list(calcset)
for x in unique_calclist:
    for y in unique_calclist[1:]:
        # in your example you didn't use combinations 
        # of duplicate valuesso I am skipping that here
        if x != y: 
            print (x, y)

使用itertools也是如此(注意这种方法假设calclists中每个列表中的值是唯一的。)

import itertools
calclists = [[1,2,3], [4,5,6], [7,8,9]]
comb_itr = itertools.combinations(itertools.chain.from_iterable(calclists), 2)
for comb in comb_itr:
    print comb

如果您不能假设每个列表中的所有值都是唯一的,您可以将上述两种方法结合起来,如下所示:

import itertools
calclists = [[1,2,3], [4,5,6], [1, 2, 3]]
calcset = set()
for calclist in calclists:
    for x in calclist:
        calcset.add(x)

comb_itr = itertools.combinations(calcset, 2)
for comb in comb_itr:
    print comb

答案 1 :(得分:0)

正如其他人所说的那样,有点难以理解,但是关于你所说的和关闭代码,我认为csv的DictReader和DictWriter是你正在寻找的。

http://docs.python.org/2/library/csv.html#csv.DictReader http://docs.python.org/2/library/csv.html#csv.DictWriter

使用这些,如果你只需要操作csv的x列中的三列,并且你知道那些列名,你可以通过列名调用每行的相应列(我建议制作那些列名常量)。基本上,每一行都成为一个字典,其中每个键都是一个列名,值是该行的元素。