【问题标题】:How to index and automate processing of list using input csv file如何使用输入 csv 文件索引和自动处理列表
【发布时间】:2011-03-08 01:53:13
【问题描述】:

我有 csv 输入文件,我们称之为 heights.csv。我的示例文件只有四行,但不能限制。 第一列只包含不相关的名称,第二列包含我想要处理为整数的值。

1000,57020,
2003,56095,
2007,55964,
3001,57020,

我想执行如下操作:

first_read_a = 第一行的值 + 第一个 random.randint(500, 1000)
second_read_a = 第一行的值 + first_read - 下一行的值
third_read_a = 第一行的值 + random.randint(500, 1000) - 下一行的值
Fourth_read_a = 第一行的值 + random.randint(500, 1000) - 下一行的值

如果列表会更长,直到最后一行没有下一行且没有下一个要减去的值,则依此类推。
该过程的结果必须以某种方式存储和索引,因为下一个任务
是使用生成的值向后执行类似的操作。

first_read_b = 最后一行的值 + Fourth_read_a - 最后一行的值

依此类推,直到这次从列表开头的第二行,而不是第一行。
我有示例代码,但它非常有限,我想问你一个有效的解决方案的例子。

import random
a = [57020, 56095, 55964, 57020]

compute = input(">")

if compute == 1: 
    read_0a = random.randint(500,1000)                
    read_1a = a[0] + read_0a - a[1]                 
    read_2a = a[1] + random.randint(500,2300) - a[2]
    read_3a = a[2] + random.randint(500,2300) - a[3]

    read_1b = a[3] + read_3a - a[2]              
    read_2b = a[2] + read_2a - a[1]                


    print read_0a, read_1a, read_2b, read_2a, read_1b, read_3a
    print read_1a + read_2a + read_3a
    print read_0a + read_1b + read_2b

交易是将脚本开发成这样的形式,它可以处理输入 *.csv 文件并按照我的示例脚本中的方式生成合适的整数,但无需定义列表 ['a' list在示例中] 手动并为每个“read”说明如何生成它。我想知道,如何索引 csv 文件以及如何将索引项作为整数而不是字符串访问,以及如何通过索引触发这些整数。
----------- -------------------------------------------------- --
让我解释一下。
我们有 eyquem 的高级脚本:

import csv
import random

with open('heights.csv','rb') as f: a = [int(row[1]) for row in csv.reader(f)] print 'a==',a

compute = input(">")

if compute == 1: read_a = dict((i+1,a[i] + random.randint(500,2300) - a[i+1]) for i in xrange(0,len(a)-1) )

read_a[0] = read_a[1] - a[0] + a[1]

read_b = dict( (i, a[len(a)-1] + read_a[len(a)-i] - a[len(a)-i-1])
               for i in xrange(1,len(a)-1))
print read_a, read_b

我们得到示例结果:

这是输入列表:a== [57020, 56095, 55964, 57020]<br> 并生成“读取”:
{0: 1637, 1: 2562, 2: 1991, 3: 4} {1: 1060, 2: 2916}

让我们检查一下:
57020 + 1637 - 2562 = 56095 [正确!因为它等于列表中的第二个值]
所以让我们取列表中的第二个值并继续:
56095 + 1991 - 1060 = 57026 [错误,因为它不等于列表中的第三个值]
所以现在剩下的会给我们错误的结果。

正确的依赖关系如下:
让我向您展示我想要的结果,使用我发布的 [原始] 第一个脚本生成的“读取”示例值:
a = [57020, 56095, 55964, 57020]
57020 #列表中的第一个值
+712 #read_0a = random.randint(500,1000)
-1637 # read_1a = 1st + read_0a - 2nd
[=]56095 #列表中的第二个值
+772 #read_2b = 3rd + read_2a - 2nd
-903 #read_2a = 2nd + random.randint(500,2300) - 3rd
[=]55964 #列表中的第三个值
+1279 #read_1b = 4th] + read_3a - 3rd
-223 #read_3a = 3rd + random.randint(500,2300) - 4th
[=]5720 #列表中的第 4 个值

就是这样。
当您从列表中的第一个值运行并按照我上面显示的方式生成“读取”的连续值时,您将获得最后一个值,在我们的示例中为第四个值,获得第二和第三值。

现在看看生成的 reads 的最终检查:

check_a = read_1a + read_2a + read_3a
check_b = read_0a + read_1b + read_2b

...您会看到 check_a 中的值总和 = check_b 中的值总和

仅当第一行和最后一行具有相同的值时,上述检查才具有权威性 - 在示例文件中为 57020。
如果第一行和最后一行的值不同,则检查必须是这样的:
first_line_value - last_line_value=(read_0a + read_1b + read_2b) - (read_1a + read_2a + read_3a)。 所以我们可以更恰当地说:
first_line_value - last_line_value = reads_backward 的总和 - reads_onward 的总和
我希望它能帮助您了解必须实现的目标。
并感谢您的耐心等待。

--------------- ------------------------------------------------

eyquem 的脚本真的很棒!
并且完全实现了我对这一刻的指示,但在我的问题结束时,我希望你考虑一些额外的事情,我希望,不需要重写整个代码

1]第一个是输入,“heights.csv”文件。
程序是否有可能接受带有小数点“.”的值
但只是在计算过程中忽略它?? 输入 csv 文件将如下所示:
1000,57.020,
2003,56.095,
2007,55.964,
3001,57.020,

但为了计算“读取”,将使用以下整数:57020、56095、55964、57020

2]接下来是自动重新计算能力。
有时,在计算过程中,我们的“读取”显示为带负数的负值,例如:
a== [57020, 56095, 55964, 57020]
read_a== {1: 1984, 2: 2128, 3: -452}
read_b== {1: 604, 2: 1997, 3: 1059}
在这个结果中,我们看到 '-452'
在这种情况下,脚本应该重新计算,直到 'reads' 中没有负值

3] 最后是一个输出文件,例如 'output.txt' 是否可以生成包含生成的“读取”的此类文件?
模板如下所示:
[1] # 方括号中的订单号
1= 1000 # 名称取自输入文件的第一列,总是以'1='开头
4=2118 # 生成的'read',总是以'4='开头
[2]
1=2003
4=3043

[3]
1=
4=2054

[4]
1=2007
4=2185

[5]
1= b>
4=2263

[6]
1=3001
4=1207

如您所见,名称取自输入文件的第一列,始终以“1=”开头,必须出现在第一个和最后一个“读取”中,然后仅出现在所有“向后读取”

【问题讨论】:

  • 这似乎很随意。了解您要完成的工作可能真的很有帮助。
  • 嗯,我尽我所能从这个脚本的内容中理解和概念化它,因为完整的解释会插入不必要的相当复杂的理论,即我国的土地测量程序之一。跨度>
  • 你归属于我的剧本是eyquem写的。
  • @daikini 您应该从一开始就明确指出,文件的第一行和最后一行必须具有相同的值。这是 sum(read_a)==sum(read_b) 的必要条件
  • 如果我的例子让你误入歧途的话,我当然会这么说。这只是巧合,文件的第一行和最后一行在我的示例中具有相同的值。这不是规则。很抱歉。

标签: python csv


【解决方案1】:

嗯,我希望你成功地解决了你的问题。

您是否找到了如何在值中使用'.' 进行管理?这很简单:

replace('.','')

对我来说,我认为以下代码满足所有要求。我希望这不是功课,你学到了一些东西。

import csv
import random
from sys import exit

with open('heights.csv','rb') as f:
    names,a = {},{}
    for k,row in enumerate(csv.reader(f)):
        names[k] = row[0]
        a[k]     = int(row[1].replace('.',''))
    print names
    print 'a==',a
    L = len(a)

compute = input(">")

if compute == 1:

    if a[1] - a[0] <= 1000 and all(a[i] - a[i-1] <= 2300 for i in xrange(2,L)):

        read_b = {L-1 : random.randint( max(500,a[1]-a[0]), 1000 ) }
        read_a = {1   : a[0] + read_b[L-1] - a[1] }

        for i in xrange(2,L):
            read_b[L-i] = random.randint( max(500,a[i]-a[i-1]), 2300 )
            read_a[i] = a[i-1] + read_b[L-i] - a[i]

    else:
        exit("The file can't be treated because of the relative values of "
             "the following couples of lines : "+\
             ('(0,1) ' if 1000 < a[1] - a[0] else "")+\
             ' '.join(repr((i-1,i)) for i in xrange(2,L) if 2300 < a[i] - a[i-1]))



    with open('output.txt','w') as fw:
        fw.write('[1]\n1={}\n4={}\n\n[2]\n1={}\n4={}\n\n'.\
                 format(names[0],read_b[L-1],names[1],read_a[1]))

        fw.writelines('[{}]\n1=\n4={}\n\n[{}]\n1={}\n4={}\n\n'.\
                      format(str(2*k-1),read_b[L-k],str(2*k),names[k],read_a[k])
                      for k in xrange(2,L))                           



    # display of the execution

    print 'read_a== %s\nread_b== %s\n\n' % (read_a,read_b)+\
          ''+\
          ('\n'.join(('  a[%s] ========== %s ******' % (y,a[y])+\
                      '\n    +read_b[%s] == %s' % (str(L-y-1), read_b[L-y-1])+\
                      '\n    -read_a[%s] == %s' % (str(y+1)  ,-read_a[y+1]  ) )
                     for y in xrange(L-1)) )+\
          '\n  a[%s] ========== %s ******\n\n' % (L-1,a[L-1])+\
          ''+\
          ('\n'.join(('  a[%s] ========== %s ******' % (y,a[y])+\
                      '\n    +read_a[%s] == %s' % (y  , read_a[y]  )+\
                      '\n    -read_b[%s] == %s' % (L-y,-read_b[L-y]) )
                     for y in xrange(L-1,0,-1)) )+\
          '\n  a[%s] ========== %s ******\n\n' % (0,a[0])+\
          ''+\
          'sum(read_a.values())== %s\nsum(read_b.values())== %s' %\
          (sum(read_a.values()),sum(read_b.values()))

.

解释:

.

read_b 变量的值由 randint() 创建。如果每个randint() 中的边界被认为是不可触碰的约束,那么肯定的条件就取决于read_a 变量的值。

你写的:

read_0a = random.randint(500,1000)  
read_1a = a[0] + read_0a - a[1]

也就是说

read_a[0] = random.randint(500,1000)  
read_a[1] = a[0] + read_a[0] - a[1]
# nota bene: read_a[0] is in fact read_b[len(a)-1]

仅当 0

时,才验证条件 0 >

也就是说如果a[1] - a[0] (E)

所以,有3种情况:

  • 如果 a[1] - a[0] 为真,则 (E) 对于任何值都为真read_a[0]read_a[0] = random.randint(500,1000)定义

  • 如果 500 为 True ,则 (E) 仅对于值 read_a[0] 为 True strong> 由read_a[0] = random.randint(a[1] - a[0] ,1000) 定义

  • 如果 1000 为 True ,则不可能找到 500 到 1000 之间的值作为 read_a[0 的值] 所以 read_a[1] 的值为正。

我们可以考虑重复指令read_a[0] = random.randint(500,1000),即read_b[len(a)-1] = random.randint(500,1000),直到read_a[0]的值符合条件read_a[1] >= 0强>。

但如果 1000 ,就会出现无限循环。这意味着文件中的值不能是没有条件的任何整数:它们必须验证一些条件才能使所有 read_a 值都是正数。而且我把这个条件的验证放到了代码里。

.

read_a 中的其他值也一样,有边界

randint(500,2300)

【讨论】:

  • @eyquem 哦,不,它既不是功课,也不是商业用途,别担心。你的工作真的很有帮助,因为我确切地知道这个脚本的用途,这有助于我理解一些在 python 中编程的高级技术。真的,真的谢谢!我只是希望完成任务能给你带来一点满足感,或者至少让你的编程技能有所提高。再次感谢。
  • @eyquem 有些事情不太好,因为脚本生成了太多读取。我们生成了 8 次读取,而不是示例输入文件需要的 6 次,因此超过了 2 次读取。如果你检查 output.txt 文件,你会看到,最后一点是两次。
  • @daikini 成功帮助别人的满足感并不小。 Python 也很有趣。 -- 我忘了提到我认为randint() 调用的界限是确定的和不可修改的。如果是这样,算法应该是不同的。这取决于程序的目标。如果这一点是确定的,请告诉我。 -- 再看代码,关于执行的显示我改成了sn -p。原因是print 'aaa\nbbb'+'\nccc'的执行速度比print 'aaa' print 'bbb' print 'ccc'
  • @daikini 当您认为可以解决此问题时,您可以对我的答案进行投票并接受其中一个(通过单击按钮下的人字形条纹)否决票,在左边)如果你认为他们足够有价值。我通知你是因为你在 stackoverflow 上的新功能。
  • @daikini 你只需要删除fw.write('[{}]\n1=\n4={}\n\n[{}]\n1={}\n4={}\n'.\ format(str(2*L-1),read_b[1],str(2*L),names[L-1],read_a[L-1]))
【解决方案2】:
from random import randint

compute = input(">")

if compute == 1:

    # If you have to store it anyway, might as well go whole-hog:
    vals = [int(l.split(",")[1]) for l in open("heights.csv").readlines()]

    reads[0] = vals[0] + randint(500, 1000)
    for i in xrange(len(vals) - 1):
        reads.append(vals[i-1] + randint(500, 1000) - vals[i])
        # not sure what to do with the last value

【讨论】:

  • 首先我要感谢您的帮助。您发布的最后一个脚本已开始满足我的要求,并且几乎是正确的方向。请查看我编辑的问题,以更好地了解还需要做什么。
  • @diakini 我认为我的示例已经完成了您所描述的操作,包括演示如何打开和解析 csv 文件,将干净的字符串转换为整数。它唯一不做的就是“向后执行类似的动作”。我认为您可以对其进行调整或提出更具体的问题?
  • @kojiro 是的,你是对的,我认为你用几行 python 代码完成的工作真的很棒。我会请你检查我刚刚添加的解释的第二部分。我希望它能让你完全理解这个想法。
  • @daikini 你看我的回答了吗?我刚刚看到您编辑了您的问题,我将对其进行研究。但在我的回答中有落后的待遇
  • @eyquem 是的,我读过。对不起,我对您的解决方案保持沉默。我猜你的第二个更接近目标的剧本与小次郎的剧本有同样的“弱点”。完全向后处理存在某种故障,因为当我们第一次前进时,我们得到的值主要取决于随机生成的整数,除了第二次“读取”,它依赖于严格的算术关系并且属于向后“读取”。第二部分,当我们向后移动时更复杂,因为我们在此处理期间获得的所有值都取决于严格的算术关系......
【解决方案3】:
import csv
import random

with open('fofo.txt','rb') as f:
    rd = csv.reader(f)
    a = [int(row[1]) for row in rd]
    print 'a==',a

(.... to be continued by daikini's code...)

rd = csv.reader(f) 是一个迭代器,当使用rd.next() 刺激或在 for 循环期间返回 csv 文件的一行。 该文件必须以读取二进制模式打开'rb'

将项目放在列表中a 只是按列表的索引对其进行索引。

.

以下代码已被编辑:

-- 我在read_b 的定义中用a[len(a)-i] 更正了a[len(a)-1]

-- 我将random.randint(500,2300) 放在R 的列表中,超出了read_a 的定义

-- 用 read_a[0] = a[1] + read_a[1] - a[0] 定义 read_a[0] 没有真正的兴趣。事实上 read_a[0] 正是 R[0] 。我去掉了这条线

--其实也可以定义read_b[3]。原来是read_a[0];因此R[0]==read_a[0]==read_b[3]!--

.

import csv
import random

with open('heights.csv','rb') as f:
    a = [int(row[1]) for row in csv.reader(f)]
    print 'a==',a

compute = input(">")
if compute == 1:

    R = [random.randint(500,2300) for j in xrange(len(a)-1)]

    read_a = dict((i+1,a[i] + R[i] - a[i+1])
                  for i in xrange(0,len(a)-1) )

    read_b = dict( (i, a[len(a)-i] + read_a[len(a)-i] - a[len(a)-i-1])
                   for i in xrange(1,len(a)))




    print 'R==',R
    print 'read_a==',read_a
    print 'read_b==',read_b
    print

    for y in xrange(len(a)-1):
        print '  a[%s] ========== %s ******' % (y,a[y])
        print '      +R[%s]    == %s' % (str(y),R[y])
        print '    -read_a[%s] == %s' % (str(y+1),-read_a[y+1])
    print '  a[%s] ========== %s ******' % (len(a)-1,a[len(a)-1])
    print '\n'

    #print ' a['+str(len(a)-1)+']==',a[len(a)-1]
    for y in xrange(len(a)-1,0,-1):
        print '  a[%s] ========== %s ******' % (y,a[y])
        print '    +read_a[%s] == %s' % (y,read_a[y])
        print '    -read_b[%s] == %s' % (len(a)-y,-read_b[len(a)-y])
    print '  a[%s] ========== %s ******' % (0,a[0])
    print '\n'

    print 'sum(read_a.values())==',sum(read_a.values())
    print 'sum(read_b.values())===',sum(read_b.values())

.

最后,我们注意到read_b.values() = R[::-1] 那么代码可以简化为:

import csv
import random

with open('heights.csv','rb') as f:
    a = [int(row[1]) for row in csv.reader(f)]
    print 'a==',a

compute = input(">")

if compute == 1:

    read_b = dict((j+1,random.randint(500,2300)) for j in xrange(len(a)-1))

    read_a = dict((i,a[i-1] + read_b[len(a)-i] - a[i])
                  for i in xrange(1,len(a)) )



    print 'read_a==',read_a
    print 'read_b==',read_b
    print

    for y in xrange(len(a)-1):
        print '  a[%s] ========== %s ******' % (y,a[y])
        print '    +read_b[%s] == %s' % (str(len(a)-y-1),read_b[len(a)-y-1])
        print '    -read_a[%s] == %s' % (str(y+1),-read_a[y+1])
    print '  a[%s] ========== %s ******' % (len(a)-1,a[len(a)-1])
    print '\n'

    for y in xrange(len(a)-1,0,-1):
        print '  a[%s] ========== %s ******' % (y,a[y])
        print '    +read_a[%s] == %s' % (y,read_a[y])
        print '    -read_b[%s] == %s' % (len(a)-y,-read_b[len(a)-y])
    print '  a[%s] ========== %s ******' % (0,a[0])
    print '\n'

    print 'sum(read_a.values())==',sum(read_a.values())
    print 'sum(read_b.values())==',sum(read_b.values())

这些代码可用于任意行数 >= 2

.

关于正数的条件:

read_b 中的数字首先被计算。所以我搜索使read_b 始终为正的条件:

因为 read_a[i] = a[i-1] + read_b[len(a)-i] - a[i]

=> read_b[len(a)-i] = read_a[i] + a[i] - a[i-1]

=> read_b[j] = read_a[len(a)-j] + a[len(a)-j] - a[len(a)-j-1]

因为我们必须有 0

=> a[len(a)-j] - a[len(a)-j-1]

=> a[len(a)-j] - a[len(a)-j-1]

=> 我们必须有 a[len(a)-j] - a[len(a)-j-1] + 1

然后条件

max(a[len(a)-j] - a[len(a)-j-1]  + 1 , 500))  <= read_b[j] 

我说的对吗?

【讨论】:

  • 啊啊啊啊...所以他想知道如何读取 csv 文件?我不得不看了五遍才能理解为什么它看起来就像你复制了他的代码并提供了它作为答案!
  • 我想这就是他想要的,这对我来说似乎很简单,但是我想知道除了读取文件的问题之外还有什么?
  • 肯定 csv 对于只抓取文件的第二列是矫枉过正?
  • @kojiro 当我不使用解析器读取文件时,总有人告诉我绝对不能使用内置函数或正则表达式来读取文件....
  • @eyquem 你的脚本看起来棒极了。真的很感谢你来分析我冗长而不清楚的查询。如果它不会滥用你,请看一下我写给我的问题的最后第三部分。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-23
  • 2019-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多