有效解析csv文件中的值

时间:2014-07-07 21:09:36

标签: python parsing dictionary

我有一个.csv格式,我需要索引或在字典中的标题,以便找到和替换字段。有人可以帮我找到更好的方法吗?

示例:

header      1990_X   1991_X   1990_B    1991_B

            ''        1       4         0
            5         0       ''        -3

输出应查找连续年份匹配的第一个正值,并替换任何' null'带有0的值只留下它。所以输出更新如下到新的.csv

         0        1        4         0
         5        0        0         -3

我遇到了负值的问题以及并不总是有数字的事实。我也担心输出我正在处理的方式是每行使用字典来定位年份。该文件有超过150和750,000行。

def stripMatch(match):
string = str(match)
strip = string.strip("'[]'")
return strip

如果名称 ==' 主要':

fn = 'test.csv'

with open(fn) as f:
    reader=csv.reader(f, delimiter=',', quoting=csv.QUOTE_NONE)
    header=next(reader)
    print header
    print "Number of fields: %s" %(len(header))

    for row in reader:
        #print row
        posKey = 0
        data={}
        for field,key in zip(row,header):
            #print '%s , %s ' %(field,key)
            value = stripMatch(field)
            data.setdefault(key, []).append(value)
            if value.isalnum() == True and int(value) > 0:
                        print "Above zero found: %d at key: %s \n " %(int(field),key)
                        posKey = key
        print "Before : %s " % data

        for d in data:
            #print d,data[d],posKey
            ##if d.startswith(posKey):
            if d[:4] == posKey[:4]:
                #print "Found it"
                print d,data[d],posKey
                numCheck = stripMatch(data[d])
                print numCheck
                print numCheck.isalnum()
                if numCheck.isalnum() == False:
                    ## Replace it with a 0
                    data[d] = 0
                    print "processing %s " % data[d]



        print "After %s " % data
        print '\n'

1 个答案:

答案 0 :(得分:0)

我不完全确定你要完成的任务,但是让我给你一些提示,以便朝着正确的方向前进:

  1. 使用DictReader代替标准阅读器会为您提供该行的字典 reader = csv.DictReader(f, delimiter=',', quoting=csv.QUOTE_NONE)
    除非您明确指定它具有不同的行,否则它将自动使用第一行作为标题。
  2. 函数stripMatch有什么作用?这似乎很重要。
  3. 此外,为什么你使用stripMatch两次 - 一次构建你的data dict,一次迭代它?
  4. posKey表示什么?当您遍历行时,您将覆盖其值。您是否保证每行只有一个值为int> 0?你的例子另有说明。所有提供给你的是 last 键,它有一个int> 0值。
  5. 您使用setdefault为每个密钥实例化列表是否有特殊原因?这意味着您拥有具有相同名称的列。
  6. 检查整数值> try / except子句可能会更好地服务0,就像在这个例子中一样:
  7. 例如:

    valid = False
    try:
        valid = int(value) > 0
    except ValueError:
        value = 0
    

    对我而言,这更能说明您正在寻找整数>这样,它也可以很容易地替换非整数字符,同时仍然尊重负数。

    我仍然不清楚你究竟要解决什么问题,所以这可能不会完全有用。但对我来说,这是一件更清晰,更直接的事情。也许你可以调整它以更好地满足你的需求:

    with open(fn) as f:
        reader = csv.DictReader(f, delimiter=',', quoting=csv.QUOTE_NONE)
        for row in reader:
            out = {}
            for key, val in row.iteritems():
                value = stripMatch(val)
    
                valid = False
                try:
                    # All values become ints. Non-ints raise ValueError
                    value = int(value)
                    valid = value > 0
                except ValueError:
                    # If the value = int(value) statement raises,
                    # valid will still be False
                    value = 0
    
                # HERE is a good place for setdefault. This way we can simply see
                # Which years have more than one valid value
                if valid:
                    out.setdefault(key[:4], []).append(value)
    
                # The above try-except ensures that all values are now ints
                # If you need to work with the entire row, this statement will
                # Normalize so that you can work with it as a dict of int values
                # If you odn't need to work with it later, this part can be omitted
                row[key] = value
    
            # Now if we need to find the years with more than one valid value,
            # We can simply iterate over the dict `out`
            for year, val_list in out.iteritems():
                if len(val_list) > 1:
                    print year
                    # Do something with year, or with the values you have