我有一个.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'
答案 0 :(得分:0)
我不完全确定你要完成的任务,但是让我给你一些提示,以便朝着正确的方向前进:
reader = csv.DictReader(f, delimiter=',', quoting=csv.QUOTE_NONE)
stripMatch
有什么作用?这似乎很重要。stripMatch
两次 - 一次构建你的data
dict,一次迭代它?posKey
表示什么?当您遍历行时,您将覆盖其值。您是否保证每行只有一个值为int> 0?你的例子另有说明。所有提供给你的是 last 键,它有一个int> 0值。setdefault
为每个密钥实例化列表是否有特殊原因?这意味着您拥有具有相同名称的列。例如:
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