按列数据过滤掉csv行

时间:2014-06-20 12:38:22

标签: python csv filter

我不知道怎么称呼这个,但我有一个带有数据的csv:

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

所以我想要做的只是保留最新的条目(在这种情况下它将是row4),我真的很难绕过这个。

我最初的想法是将数据从csv读取到行列表,然后:

  1. 将日期字符串转换为 datetime 对象
  2. 然后浏览每一行,获取它的名称并与其他每一行进行比较,以找到最高日期并保存日期的行。
  3. 有没有更好的方法来解决这个问题?

3 个答案:

答案 0 :(得分: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 :(得分: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

答案 2 :(得分: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

可能有更优雅的方式