3

所以,我有一个我认为很难解决的问题,我有一个脚本可以循环通过 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 列表的标题列表,那么可能会以这种格式创建一个标题(记住每次脚本运行都有三个标题)"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

4

2 回答 2

1

我不确定我是否正确理解了这个问题,所以这可能完全不符合标准,但如果你只是想要出现在所有 calclists 中的数字的所有唯一组合,你可以像这样处理它:

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
于 2013-11-14T05:41:58.633 回答
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 列中的三个,并且您知道这些列名,则可以通过列名调用每行的相应列(我建议将这些列名设为常量)。基本上,每一行都成为一个字典,其中每个键是一个列名,值是该行的元素。

于 2013-11-18T23:50:21.003 回答