Python2.7 - 将参数传递给命令行以根据参数过滤CSV

Posted

技术标签:

【中文标题】Python2.7 - 将参数传递给命令行以根据参数过滤CSV【英文标题】:Python2.7 - Passing argument to command line to filter CSV according to parameter 【发布时间】:2016-03-22 14:45:49 【问题描述】:

我还没有这方面的代码,因为我不知道如何解决。 使用sci-kitpython 中的tfidfVectorizer,我计算了电影评论中使用的术语的tfidf 分数。

我将结果输出到一个 CSV 文件中,其中包含 4 列

Col1 = indDocID 
Col2 = Word 
Col3 = MovieID 
Col4 = Score

我想传递一个命令行参数,该参数将解析 CSV 文件并仅打印与 MovieID 对应的结果。

这样,我可以直接从命令行调用我感兴趣的结果作为文件$python tfidf.py -i uniqMovieID

我一直在阅读有关传递命令行参数的所有文献,并一直在试验我的代码,但它们似乎没有解决我过滤包含相同 @987654331 的信息的问题@ 我直接在命令行中指出。

CSV 文件中的数据示例是

indDocID,Word,MovieID,Score
1,love,4583B,.09
2,good,4583B,.37
3,funny,4583B,.64
4,love,34623C,.34
5,hate,34623C,.57

我的目标是使用以下命令 python tfidf.py -i 4583B 运行脚本,结果是:

indDocID,Word,MovieID,Score
1,love,4583B,.09
2,good,4583B,.37
3,funny,4583B,.64

我一直在寻找here 并尝试了某些示例,例如

from optparse import OptionParser

parser = OptionParser()
parser.add_option("-i", "--idMovie", dest="arg",
                  help="insertMovieIds", metavar="variable")

还有这个:

def main(argv):
   movieIds = ''

   try:
      opts, args = getopt.getopt(argv,"hi:",["movieid="])
   except getopt.GetoptError:
      print 'test.py -i <movieID>'
      sys.exit(1)
   for opt, arg in opts:
      if opt == '-h':
         print 'tfidf.py -i <movieIds>'
         sys.exit()
      elif opt in ("-i", "--id"):
         movieIds = arg

   print 'MovieID is:', movieIds



if __name__ == "__main__":
   main(sys.argv[1:])

但我不确定如何成功地将它们集成到我的代码中,以便将其关联到我的 CSV 中的特定行以达到上述预期结果。

【问题讨论】:

您尝试过使用熊猫pandas.pydata.org 吗? 我们一直在努力避免使用不可避免的数据库,方法是附加到 CSV 以不断更新我们的列表。尽管@DainDwarf,熊猫将是下一步 optparsesys.argv 只是将数字/字符串放入程序的方法。使用它来过滤csv 数据是一个明显的问题。 【参考方案1】:

使用csv.DictReader 提取与传入脚本的唯一MovieID 匹配的任何行:

import csv
from optparse import OptionParser

parser = OptionParser()
parser.add_option("-i", "--idMovie", dest="arg",
                  help="insertMovieIds", metavar="variable")
opt, args = parser.parse_args()
un_id = opt.arg
with open("out.txt") as f:
    names = next(f).rstrip().split(",")
    r = csv.DictReader(f, fieldnames=names)
    print(",".join(names))
    for d in r:
        if un_id == d["MovieID"]:
            print(",".join([d[n] for n in names]))

输出:

$ python test.py -i 4583B 
indDocID,Word,MovieID,Score
1,love,4583B,.09
2,good,4583B,.37
3,funny,4583B,.64

您需要重新添加错误检查等。如果您想为不同的列重用代码,只需将逻辑放在一个函数中,如果您找到匹配项并且如果没有匹配项,您也可能只想打印标题发现向用户报告:

def find_by_val(col, k, fle, delim=","):
    with open(fle) as f:
        names = next(f).rstrip().split(delim)
        if col not in names:
            print("Column does not exist.")
            return
        r, found = csv.DictReader(f, fieldnames=names), False
        for d in r:
            if un_id == d[col]:
                if not found:
                    print(",".join(names))
                    print(",".join([d[n] for n in names]))
                    found = True
                else:
                    print(",".join([d[n] for n in names]))
        if not found:
            print("No matching value for  found".format(k))

输出:

padraic@lab:~$ python test.py -i 4583B 
indDocID,Word,MovieID,Score
1,love,4583B,.09
2,good,4583B,.37
3,funny,4583B,.64
padraic@lab:~$ python test.py -i foo
No matching value for foo found

如果你将输出存储在列表中,你可以写得更简洁一些:

def find_by_val(col, k, fle, delim=","):
    with open(fle) as f:
        names = next(f).rstrip().split(delim)
        if col not in names:
            print("Column does not exist.")
            return
        r, found = csv.DictReader(f, fieldnames=names), False
        output = [",".join(d[n] for n in names) for d in r if d[col] == k ]
        if not output:
            print("No matching value for  found".format(k))
        else:
            print(",".join(names))
            print("\n".join(output))

如果您想要更通用的方法,您还应该将列名作为参数并获取多个值。

【讨论】:

优秀。工作绝对像一个魅力。它的通用性也很有用,以防我将来需要用不同的变量进行解析。非常有用。【参考方案2】:

如果您只需要使用附加参数将行与 MoveID 匹配,则 -i 可能是不必要的(如果您需要指定我们用于匹配的列,附加参数可能会有所帮助)。你可以用python tfidf.py 4583B测试下面的代码

#!/usr/bin/env python

import sys, csv

def search(db, mid):
    # open csv file
    with open(db, 'r') as csvfile:
        reader = csv.reader(csvfile, delimiter=',')
        for r in reader:
            # print line if MovieID matches
            if r[2] == mid:
                print(','.join(r))

if __name__ == '__main__':
    # parse arguments    
    db, mid = sys.argv[1:]
    search(db, mid)

【讨论】:

这不是一个非常通用的方法,你必须知道列索引

以上是关于Python2.7 - 将参数传递给命令行以根据参数过滤CSV的主要内容,如果未能解决你的问题,请参考以下文章

将输入参数传递给 Theano 函数的正确方法是啥?

将参数传递给查询访问 VBA

如何从类定义中将参数传递给元类?

c++ 在创建时将构造函数参数从父对象传递给子对象

使用 docker run 命令将参数传递给 Dockerfile 中的 CMD

将参数输入参数传递给批处理文件