csv-fi中值的有效解析

2024-10-03 06:29:22 发布

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

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

示例:

header      1990_X   1991_X   1990_B    1991_B

            ''        1       4         0
            5         0       ''        -3

输出应该在年份匹配的行中查找第一个正值,并用0替换任何“null”值,否则就不用管它了。所以下面的输出更新为new.csv

         0        1        4         0
         5        0        0         -3

我遇到了一个负值的问题,而且事实上并不总是有数字。我还担心输出,因为我目前处理的方式是每行使用一个字典来定位年份。这个文件有150到75万行。你知道吗

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

如果名称=='main':

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'

Tags: csvkeyfieldfordataifvaluereader
1条回答
网友
1楼 · 发布于 2024-10-03 06:29:22

我不完全确定你想要完成什么,但让我给你一些提示,让你朝着正确的方向前进:

  1. 使用DictReader而不是标准读取器将为该行提供字典。
    reader = csv.DictReader(f, delimiter=',', quoting=csv.QUOTE_NONE)
    它将自动使用第一行作为标题,除非您明确指定它具有不同的标题。你知道吗
  2. 函数stripMatch做什么?看来这里很重要。你知道吗
  3. 此外,为什么要使用stripMatch两次—一次是在构建datadict时,一次是在迭代它时?你知道吗
  4. posKey表示什么?当您在您的行上迭代时,您正在覆盖它的值。是否保证每行只有一个int>;0的值?你的例子显示了另一种情况。提供给您的只是具有int>;0值的last键。你知道吗
  5. 使用setdefault为每个键实例化一个列表有什么特别的原因吗?这意味着您有同名的列。你知道吗
  6. 检查整数值>;0可能最好使用try/except子句,如下例所示:

例如:

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

对我来说,这更表明您正在寻找整数>;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

相关问题 更多 >