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

时间:2015-12-16 12:45:23

标签: python csv argparse

我还没有代码,因为我不确定如何解决。 使用tfidfVectorizer sci-kit中的python,我计算了电影评论中使用的术语的tfidf分数。

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

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

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

通过这种方式,直接从命令行,我可以将我感兴趣的结果称为文件$python tfidf.py -i uniqMovieID

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

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中的特定行相关联,以达到上述预期结果。

2 个答案:

答案 0 :(得分:0)

使用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

你需要添加你的错误检查等等。如果你想重用不同cols的代码只是把逻辑放到一个函数,你也可能只想找到一个匹配的打印头,如果没有匹配找到报告给用户:

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))

您还应该将列名作为参数,如果您想要更通用的方法,可以使用多个值来查找。

答案 1 :(得分:0)

如果只需要使用附加参数匹配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)