按列数据过滤CSV行

1 投票
3 回答
1422 浏览
提问于 2025-04-18 10:29

我不太确定该怎么称呼这个问题,但我有一个包含数据的csv文件:

...|Address    | Date       |...  
...|Abraham st.| 01/01/2008 |...  
...|Abraham st.| 02/02/2007 |...  
...|Abraham st.| 03/03/2011|...  

我想做的就是只保留最新的一条记录(在这个例子中就是第4行),我真的很难理解该怎么做。

我最初的想法是先把csv里的数据读到一个行的列表中,然后:

  1. 把日期字符串转换成datetime对象
  2. 然后逐行检查,获取每一行的名字,并和其他每一行进行比较,找出日期最新的那一行,并保存下来。

有没有更好的方法来处理这个问题呢?

3 个回答

0

我不太确定你是否真的需要“和每一行进行比较”(不过这可能是我误解了你的意思)。我会在遍历这一列的时候,简单地把最新的一行保存下来。

可以用这样的伪代码来表示:

saved_row = Null
for row in table:
    if not saved_row:
        saved_row = row
    else if row.date > saved_row.date:
        saved_row = row

其实还有更优雅的方法可以把初始行存到 saved_row 里。

2

要记住到目前为止看到的最高值;我假设你已经有一个csv.reader()对象在读取CSV数据:

from datetime import datetime

max_date = datetime.min
newest_row = None

for row in csv_reader:
    # assumption: your date is the 4th column in each row
    date = datetime.strptime(row[3], '%m/%d/%Y')
    if date > max_date:
        # row is newer, remember it
        max_date = date
        newest_row = row

当你读完整个文件后,newest_row会保存最近日期的数据行。不过,程序在内存中最多只会保留2行数据(当前正在处理的行和找到的最新行)。

注意,我把max_date初始化为datetime.min,这是你可以在datetime对象中存储的最小值;只要你的输入文件里没有包含公元1年1月1日的行,你就没问题。

1

只需要使用内置的 max 函数,并配合一个 key 函数,把日期字段提取出来并转换成 datetime 对象。我假设你的日期格式是 mm/dd/yyyy。

import csv
from datetime import datetime

DATE_COLUMN = 1
with open('input.csv') as f:
    reader = csv.reader(f, delimiter='|')
    next(reader)    # skip over the CSV header row
    most_recent = max(reader, key=lambda x : datetime.strptime(x[DATE_COLUMN].strip(), '%d/%m/%Y'))

>>> print most_recent
['Abraham st.', ' 03/03/2011']

我想你是想按“地址”这一列分组,然后从“日期”这一列中选出最新的日期,这样的话可以像下面这样使用 itertools.groupby()

import csv
from itertools import groupby
from datetime import datetime

ADDRESS_COLUMN = 0
DATE_COLUMN = 1
most_recent = []

with open('input.csv') as f:
    reader = csv.reader(f, delimiter='|')
    next(reader)    # skip over the CSV header row
    for k, g in groupby(sorted(reader), lambda x : x[ADDRESS_COLUMN]):
        most_recent.append(max(g, key=lambda x : datetime.strptime(x[DATE_COLUMN].strip(), '%d/%m/%Y')))

>>> print most_recent
[['Abraham st.', ' 03/03/2011'], ['Moses rd.', ' 10/12/2013'], ['Smith St.', ' 01/01/1999']]

假设 input.csv 文件里包含这些内容:

Address |Date
Abraham st.| 01/01/2008
Abraham st.| 02/02/2007
Abraham st.| 03/03/2011
Moses rd.| 10/12/2013
Moses rd.| 11/11/2011
Smith St.| 01/01/1999

撰写回答