【问题标题】:Checking a CSV file for multiple strings检查 CSV 文件中的多个字符串
【发布时间】:2017-08-08 19:45:04
【问题描述】:

这似乎是一个简单的问题,但我现在无法弄清楚。我有以下 CSV 文件:

Version,4
Name,Jon
Address,Somewhere
Date,09-16-2016
Worked,Yes
Done,No
Description,Something

我想检查此 CSV 是否包含 A 列中的多个字段并包含 B 列中的相关值。

我的代码如下所示:

import csv
f = csv.reader(open(file.csv))
fields = ['Name','Address','Date']

现在如果我找到一个字段和/或相关值,我想做一些特定的逻辑,例如:

for r in f:
    if r[0] in fields:
        print(r[0]+" is present in the file.csv file")
        if r[1]:
            print("Value related to "+r[0]+" is in the file.csv file")
            if r[0] == 'Date': 
                if type(datetime.datetime.strptime(r[1], '%m-%d-%Y')) == datetime.datetime:
                    print(r[0]+" value is correctly formatted")
                else:
                    print(r[0]+" value is not correctly formatted (MM-DD-YYYY)")
                    break
        else:
            print("Value related to "+r[0]+" is not filled in, in the file.csv file")
            break

这可行,但我现在如何检查 fields 列表中的任何字符串是否不在此循环的 CSV 中?也欢迎任何其他评论。

【问题讨论】:

  • 如果你为if r[0] in fields:语句添加else部分并处理它,那么你面临的问题是什么?
  • @paul_dg 是pandas 的选项吗?
  • @Haranadh 这将返回 r[0] 中不在字段中的所有值。我想检索不在 CSV 中的字段中的哪些值。
  • @Meitham 使用标准库的解决方案目前更适合我的情况。

标签: python csv


【解决方案1】:

如果您愿意给pandas 一个机会,这将很简单::

>>> import pandas as pd
>>> df = pd.read_csv('file.csv', header=None, names=['A', 'B'])
>>> df
             A           B
0      Version           4
1         Name         Jon
2      Address   Somewhere
3         Date  09-16-2016
4       Worked         Yes
5         Done          No
6  Description   Something

>>> fields = ['Name','Address','Date']
>>> df.ix[:, 'C'] = df['A'].isin(fields)
>>> df
             A           B      C
0      Version           4  False
1         Name         Jon   True
2      Address   Somewhere   True
3         Date  09-16-2016   True
4       Worked         Yes  False
5         Done          No  False
6  Description   Something  False

或者,你可以试试 ::

>>> import csv
... f = csv.reader(open('file.csv'))
... fields = ['Name','Address','Date']
... 
... 
>>> items = dict(f)
>>> items
{'Name': 'Jon', 'Version': '4', 'Done': 'No', 'Address': 'Somewhere', 'Date': '09-16-2016', 'Worked': 'Yes', 'Description': 'Something'}
>>> defined_keys = {k: v for k, v in items.items() if k in fields}
>>> defined_keys
{'Date': '09-16-2016', 'Name': 'Jon', 'Address': 'Somewhere'}
>>> undefined_keys = {k: v for k, v in items.items() if k not in fields}
>>> undefined_keys
{'Worked': 'Yes', 'Version': '4', 'Done': 'No', 'Description': 'Something'}
>>> 

此处正确的数据结构取决于您打算对数据执行的所有流程/操作。 DataFrame 在这方面非常灵活,但如果您喜欢自己滚动,那么这里的 dict 可能会这样做。

【讨论】:

    【解决方案2】:

    对于标准库方法,可能类似于:

    import csv
    import datetime
    
    reader = csv.reader(open('file.csv'))
    file_contents = {}
    for line in reader:
        file_contents[line[0]] = line[1]
    
    def is_date(s):
        return isinstance(datetime.datetime.strptime(s, '%m-%d-%Y'), datetime.datetime)
    
    fields = [('Name',lambda s: isinstance(s,str)),
              ('Address',lambda s: isinstance(s,str)),
              ('Date',is_date)]
    for field,arg_check in fields:
        if field not in file_contents:
            print('Missing field {}'.format(field))
            break
        val = file_contents[field]
        if not arg_check(val):
            print('field {} with value {} failed arg check'.format(field,val))
            break
    

    在这里,我盲目地将所有 csv 值读入字典,然后有一个元组列表来指定预期的内容。 fields 指定字段名称,后跟一个函数,该函数在使用该字段的值作为参数调用时返回 True 或 False。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-08
      • 2016-10-17
      • 1970-01-01
      • 2022-01-07
      • 2013-02-18
      • 2021-03-08
      • 2012-07-27
      • 2013-03-29
      相关资源
      最近更新 更多