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-kit
和python
中的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,熊猫将是下一步optparse
和 sys.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的主要内容,如果未能解决你的问题,请参考以下文章