【问题标题】:How can i query a specific column of a csv file that i have input and print all returned rows using python?如何查询我输入的 csv 文件的特定列并使用 python 打印所有返回的行?
【发布时间】:2016-03-11 21:16:12
【问题描述】:

所以要引导你完成它,这就是我想做的事情

1) 我想将脚本放在包含我要分析的 csv 的文件夹中

2) 运行脚本

3) 输入我要分析的 .csv 的名称

4) 输入我要搜索的单词和短语,用逗号分隔

5) 搜索并打印包含我指定的任何单词/短语的行

好的,这是我的代码

import csv


opening_text = "Make sure this script is in the same folder as file you want to analyze \n"
print opening_text

file_name = raw_input('Enter file name ending with .csv to analyze (e.g. file.csv): ')


print "\n The file that will be analyzed is " + file_name + "\n"

my_terms = raw_input('Please enter the words and phrases you would like to find in ' + file_name + ', separated by a comma:')


single_terms= my_terms.split(',')
with open(file_name, 'rb') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
    for row in spamreader:
        for term in single_terms:
            if term in row:
                print ' '.join(row)

我当前的脚本有这些问题:

1) 它不是在搜索短语。它可以分别搜索“嘿”和“那里”,但不能搜索“嘿那里”

2) 它不会清理我的输入。例如,我用逗号后跟空格来描述我的术语,但如果我要搜索的下一个短语位于句子的开头,则搜索不正确。

3) 如果搜索词的大小写与文件内容不同,则会给出不正确的结果

另外,有什么方法可以只搜索 csv 文件中的一列?例如只需搜索“评论”列。

这是包含在“sample.csv”中的示例数据,我与脚本位于同一文件夹中。

样本数据

Date;Customer Name;Comments

2/12/2015;Eric;The apples were absolutely delicious

3/10/2015;Tasha;I enjoyed the mangoes thoroughly

4/11/2014;Walter;The mangoes were awesome

3/10/2009;Ben;Who killed the cat really

9/10/2088;Lisa;Eric recommended guavas for me

【问题讨论】:

  • 使用 csv.DictReader,它返回字典。这样您就可以在特定列中进行搜索。在比较或查看字符串时将文本转换为小写。
  • 这还不是全部,@BobEzuba。 csv 阅读器的分隔符设置不正确,比较是在集合中搜索元素,而不是在字符串中。问题已正确发布,我觉得 OP 至少花费了一些努力来解决出现的问题。

标签: python regex csv


【解决方案1】:

对于所描述的情况,您可能不需要正则表达式;简单的字符串搜索就可以了。不过,让我们看看这两个版本。

首先,您使用空格 ' ' 作为分隔符,这对于您提供的 CSV 数据不正确。为了正确解析,您希望使用 ';' 作为分隔符。在您的示例中,quotechar 没有任何效果,因此您可以省略它或将其设置为常见的值。

对于以下两个版本,我使用以下内容:

file = 'sampledata/test.csv' # Target CSV file path
terms = 'enjoy, apples, the mangoes' # You want to replace this with your input

版本 1:字符串搜索

lookup = [i.strip().lower() for i in terms.split(',')]
with open(file, 'r') as csvin:
    rdr = csv.reader(csvin, delimiter=';', quotechar='"')
    header = rdr.next()
    for row in rdr:
        for l in lookup:
            if row[header.index('Comments')].lower().find(l) != -1:
                print(row)

为了帮助您完成它,以下是基本步骤:

  1. 将输入 terms 转换为可用的东西。正如您在代码中所写的那样,我将其以逗号分隔。此外,strip() 空格,因为它们会阻止您在评论的开头找到某些内容。

  2. 读取文件,设置 CSV-reader 并从第一行开始绘制标题。

  3. 对于查找列表中的每一行和每个元素,我们测试查找是否存在于字符串中的某个位置。我使用lower() 忽略大小写,尤其是在 cmets 开头。

我示例性选择的输入项的结果是:

['2/12/2015', 'Eric', 'The apples were absolutely delicious']
['3/10/2015', 'Tasha', 'I enjoyed the mangoes thoroughly']
['3/10/2015', 'Tasha', 'I enjoyed the mangoes thoroughly']
['4/11/2014', 'Walter', 'The mangoes were awesome']

注意:一条评论返回两次,因为我们在文本中找到了两个查找元素。你不能直接避免这种情况,但你可以事后处理。

版本 2:正则表达式

上述示例的大部分内容保持不变。代码如下:

lookup = [re.compile(i.strip().lower()) for i in terms.split(',')]
with open(file, 'r') as csvin:
    rdr = csv.reader(csvin, delimiter=';', quotechar='"')
    header = rdr.next()
    for row in rdr:
        for l in lookup:
            m = l.search(row[header.index('Comments')].lower())
            if m is not None:
                print(row)

区别在于第 1 步和第 3 步:

  1. 对于每个输入项,我们编译一个正则表达式并将其存储在我们的查找列表中。 注意: 在我的示例术语中,正则表达式回退到一些常规字符串搜索,因为没有使用特殊的正则表达式运算符。但是,您可以输入 mango(es)? 之类的内容。

  2. (同上)

  3. 对于每一行和每个正则表达式查找,使用 re.search() 测试 CSV 的注释列,这会产生一个正则表达式匹配对象 re.MatchObject。如果结果对象不是None,则您已找到匹配项。 注意: 使用匹配对象的start() 方法访问找到的子字符串的位置。有关更多功能,请参阅Regex Match Objects

  4. 上的文档

regex版本的结果同上:

['2/12/2015', 'Eric', 'The apples were absolutely delicious']
['3/10/2015', 'Tasha', 'I enjoyed the mangoes thoroughly']
['3/10/2015', 'Tasha', 'I enjoyed the mangoes thoroughly']
['4/11/2014', 'Walter', 'The mangoes were awesome']

另外...

您询问是否只能搜索一列。如果您从 csv 阅读器获得一行,它会给出一个字符串列表,由提供的分隔符拆分。要通过名称获取特定列,可以在最初绘制的标题行上使用index() 函数,然后使用返回的索引访问行列表中的元素。

【讨论】:

  • 嘿,非常感谢精彩的演练。这说得通。我必须重新审视定界符。我想我从来没有真正完全掌握它。正则表达式也是如此。两种解决方案都很棒,我想第二个解决方案可以做得更多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-24
相关资源
最近更新 更多