【问题标题】:How to filter a row in a csv file based on multiple indexes?如何根据多个索引过滤csv文件中的一行?
【发布时间】:2021-05-06 14:09:35
【问题描述】:

我有一个如下所示的文件:

#This is TEST-data
2020-09-07T00:00:03.230+02:00,ID-10,3,London,Manchester,London,1,1,1
2020-09-07T00:00:03.230+02:00,ID-10,3,London,London,Manchester,1,1
2020-09-07T00:00:03.230+02:00,ID-20,2,London,London,1,1
2020-09-07T00:00:03.230+02:00,ID-20,2,London,London1,1
2020-09-07T00:00:03.230+02:00,ID-30,3,Madrid,Sevila,Sevilla,1,1,1
2020-09-07T00:00:03.230+02:00,ID-30,3,Madrid,Sevilla,Madrid,1
2020-09-07T00:00:03.230+02:00,ID-40,2,Madrid,Barcelona,1,1,1,1

每行中的Index[2] 显示该特定行中有多少城市。所以第一行 index[2] 的值为 3,即London, Manchester, London.

我正在尝试执行以下操作:

对于每一行,我需要检查cities_to_filter. 中是否存在任何行 [3] + 之后提到的城市(基于城市数量)

这是我当前的代码:

path = r'c:\data\ELK\Desktop\test_data_countries.txt'

cities_to_filter = ['Sevilla', 'Manchester']

def filter_row(row):
    # amount_of_cities = row[2]    
    condition_1 = any(city in row for city in cities_to_filter)
    
    return condition_1

with open (path, 'r') as output_file:
    reader = csv.reader(output_file, delimiter = ',')
    next(reader)
    for row in reader:
        if filter_row(row):
            print(row)

我为这个数据集编写的代码可以正常工作,但由于它查看每一列,即使是我知道的不是城市的列,它也很危险。我需要我的代码根据每行包含的城市数量仅检查属于城市的列。

【问题讨论】:

  • 这看起来很有趣。您可以使用amount_of cities 创建一个新的城市列表作为cities_to_filter 的一部分。然后您使用该列表与您的cities_to_filter 进行比较
  • @NorthAfrican 说起来难,做起来难。我不想在我当前的代码中改变太多。我觉得我真的很亲近。
  • @mhawke 你到底是什么意思?
  • @mhawke 没问题,伙计,也许你仍然可以帮助我。感觉我真的很亲近。

标签: python list indexing filter


【解决方案1】:

城市“列表”总是从相同的偏移量开始,长度从row[2] 得知。因此,只需将其切出并使用您的 any() 表达式来检查要过滤的引用,或者您可以使用集合操作,但这可能是矫枉过正:

import csv

path = r'c:\data\ELK\Desktop\test_data_countries.txt'

cities_to_filter = ['Sevilla', 'Manchester']

def filter_row(row):
    count = int(row[2])
    cities = row[3:3+count]
    return any(city in cities for city in cities_to_filter)

with open (path, 'r') as input_file:
    reader = csv.reader(input_file, delimiter = ',')
    next(reader)
    for row in reader:
        if filter_row(row):
            print(row)

此外,将output_file 重命名为input_file,因为文件正在读取,而不是写入。

输出

['2020-09-07T00:00:03.230+02:00', 'ID-10', '3', 'London', 'Manchester', 'London', '1', '1', '1']
['2020-09-07T00:00:03.230+02:00', 'ID-10', '3', 'London', 'London', 'Manchester', '1', '1']
['2020-09-07T00:00:03.230+02:00', 'ID-30', '3', 'Madrid', 'Sevila', 'Sevilla', '1', '1', '1']
['2020-09-07T00:00:03.230+02:00', 'ID-30', '3', 'Madrid', 'Sevilla', 'Madrid', '1']

【讨论】:

  • 看起来很安静。 row[3:3+count] 到底在做什么?
  • row 是 CSV 文件中的字段列表。 row[3:3+count] 是该列表中的一部分。切片从索引 3 开始,一直到索引 3+count,例如对于第一行 row[2] 是 3 所以切片是 row[3:6] 这是子列表 ['London', 'Manchester', 'London'] 这是第一行的城市。在 Python 文档中查找列表切片(其他参考可用)。
  • 我们可以私聊吗?
  • @TangerCity:可能不是……关于什么?如果您有其他问题,那么您可以创建一个新帖子。这个问题写得很好,包含提供答案所需的信息。所以你可能会得到很好的回应。
  • 其实这一切都与这个问题有关。如果row[2] 有时包含不同的值,例如XXX,该怎么办。我在更大的数据集上尝试了这个并收到以下错误:ValueError: invalid literal for int() with base 10: 'XXX'。所以实际上我需要建立一个额外的前提条件,即row[2] 必须是一个数字。
猜你喜欢
  • 2021-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 2018-11-29
相关资源
最近更新 更多