【问题标题】:Find min value in a CSV and print every row that includes it in Python在 CSV 中查找最小值并在 Python 中打印包含它的每一行
【发布时间】:2014-12-09 01:20:59
【问题描述】:

非常感谢您的任何帮助。我正在尝试编写一个脚本,该脚本将遍历 csv 文件的文件夹,在第二列中找到最小值并打印包含它的每一行。脚本查看的 csv 文件如下所示:

TPN,12010,on this date,25,0.00005047619239909304377497309619
TPN,12011,on this date,23,0.00003797836224092152019127884704
TPN,12012,on this date,78,0.0001130474103447076420049393022
TPN,12020,on this date,27,0.00005671375308512314236202279053
TPN,12021,on this date,60,0.00009856619048244864701475864425

脚本如下所示:

import csv
import os

folder = '/Users/Documents/Senior/Thesis/Python/TextAnalysis/datedmatchedngrams2/'

identity = []
for filename in os.listdir (folder):
    with open(filename, 'rb') as inf:
        incsv = csv.reader(inf)
        column = 1               
        datatype = int
        data = (datatype(row[column]) for row in incsv)   
        least_value = min(data)
        print least_value
        for row in incsv:
            if least_value in column[1]:
                identity.append(row)
            else:
                print "No match"
        print identity

我得到的错误是:

  File "findfirsttrigram.py", line 12, in <module>
    identity.append("a")
NameError: name 'identity' is not defined

我也试过这样做:

import csv
import os

folder = '/Users/Documents/Senior/Thesis/Python/TextAnalysis/datedmatchedngrams2/'

for filename in os.listdir (folder):
    with open(filename, 'rb') as inf:
        incsv = csv.reader(inf)
        column = 1               
        datatype = int
        data = (datatype(row[column]) for row in incsv)   
        least_value = min(data)
        print least_value
        for row in incsv:
            if least_value in row:
                print row
            else:
                print "No match"

但这也没有用。它没有给我一个错误,但它也没有打印“不匹配”,所以我不知道从哪里开始。请帮忙!!

【问题讨论】:

    标签: python python-2.7 csv


    【解决方案1】:

    你可以这样做:

    import csv
    
    # for each_file in os.listdir (folder):    
    with open(each_file) as f:
        m=min(int(line[1]) for line in csv.reader(f))
        f.seek(0)
        for line in csv.reader(f):
            if int(line[1])==m:
                print line
    

    【讨论】:

    • 其实dawg,不幸的是,这不起作用!它只打印每个 csv 文件中的最后一行。
    • 如果您放入具有相同最小值的多行,它适用于您的示例数据。您可以在无效的地方发布数据吗?
    【解决方案2】:

    未找到最小值的原因是您在查找最小值时将列转换为int,但当您将其视为您拥有的行的一部分时它仍然是一个字符串读。尝试像这样更改您的代码:

    for row in incsv:
        if int(row[column])==least_value:
            print row
        else:
            print "No match"
    

    关于另一个错误,在with 子句中,全局identity 似乎无法访问。您可以使用global 重新引入它,也可以不使用with 子句。

    【讨论】:

    • 谢谢你,这让我更进一步,但当有一个匹配时,我一直打印不匹配!
    【解决方案3】:

    Ashalynd 介绍了价值测试失败的原因。但是,您的“不匹配”语句从未被调用的原因是因为您的 csv 阅读器无法对数据进行两次迭代。举个简单的例子吧。

    with open(filename) as inf:
        incsv = csv.reader(inf)
        total_lines = 0
        for line in incsv:
            total_lines += 1
        print total_lines
    
        total_lines = 0
        for line in incsv:
            total_lines += 1
        print total_lines
    

    假设有 999 条记录,它将输出以下内容:

    999
    0
    

    这是因为在第一次迭代结束时,文件对象的位置在末尾。您需要将其重置回文件的开头以重复数据。 inf.seek(0) 和第二个例子应该没​​问题。很确定这会起作用。

    for filename in os.listdir (folder):
        with open(filename, 'rb') as inf:
            incsv = csv.reader(inf)
            column = 1               
            datatype = int
            #This sets the file's current position to the end
            data = (datatype(row[column]) for row in incsv)   
            least_value = min(data)
            print least_value
            #This resets the file's current position to be read again
            inf.seek(0)
            for row in incsv:
                # Check if the value is the same as properly casted data
                if least_value == datatype(row[column]):
                    print row
                else:
                    print "No match"
    

    【讨论】:

    • 感谢您向我解释这一点!
    猜你喜欢
    • 2015-04-16
    • 2013-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多