【问题标题】:How to sort a CSV file by date?如何按日期对 CSV 文件进行排序?
【发布时间】:2021-09-07 09:14:13
【问题描述】:

我已经阅读了几篇关于此的帖子(123),但我还不能让它发挥作用。我有一个(简化的)CSV 文件,如下所示:

NOMBRE,APELLIDO,ID,NACIMIENTO,FECHAINGRESO,MAILPERSONAL,DEPARTAMENTO
name1,lastname1,123,2000-01-01,2021-03-13,mymail1@example-com,IT
name2,lastname2,456,1999-01-01,2020-01-21,mymail2@example-com,IT

我想根据标题FECHAINGRESO 对它进行排序,最旧的日期在前,但不知道如何做到这一点。我已经在 Ubuntu 20 中使用 python 3.8.5 尝试过这个:

import csv
import os
from datetime import datetime
# With this I read the cvs and print it to check if everything is ok
with open('Empleados.csv', newline='') as csvfile:
   spamreader = csv.reader(csvfile, delimiter=',')
   for row in spamreader:
       print(', '.join(row))
# The next is the code from several attempts where I failed to sort the cvs
with open('Empleados.csv', newline='') as csvfile:
    # I wrote 4 because I belive the position 4 in the headers' row is the one with FECHAINGRESO
    csvfile = sorted(csvfile, key = lambda row: datetime.strptime(row[4], "%d-%m-%Y"))
    print(csvfile)
    s = sorted(csvfile, key=lambda x:datetime.strptime(x[4],"%d-%m-%Y"), reverse=True)
    print(s)
    l = sorted(csvfile, key=lambda x: x[4], reverse=True)
    print(l)
    sortedlist = sorted(csvfile, key=operator.itemgetter(4), reverse=False)
    print(sortedlist)
    sortedlist = sorted(csvfile, key=lambda row: row[4], reverse=True)
    print(sortedlist)

基本上它们都不起作用,因为它像字符串一样读取行并且通常返回此错误:

  File "/home/Pruebas VSC/prueba_postgresql.py", line 31, in <module>
    csvfile = sorted(csvfile, key = lambda row: datetime.strptime(row[4], "%d-%m-%Y"))
  File "/home/Pruebas VSC/prueba_postgresql.py", line 31, in <lambda>
    csvfile = sorted(csvfile, key = lambda row: datetime.strptime(row[4], "%d-%m-%Y"))
  File "/usr/lib/python3.8/_strptime.py", line 568, in _strptime_datetime
    tt, fraction, gmtoff_fraction = _strptime(data_string, format)
  File "/usr/lib/python3.8/_strptime.py", line 349, in _strptime
    raise ValueError("time data %r does not match format %r" %
ValueError: time data 'E' does not match format '%d-%m-%Y'

其中一些不会失败,但它们不会按 CSV 列中的日期排序。

最后一个 with-open 中的所有内容都是我在 google 中找到的其他问题的代码,但我不明白所有内容。希望有人可以帮助我了解如何对这个列表进行排序。我想稍后保存 CSV 文件,但我相信它在排序后应该很容易写入。

【问题讨论】:

  • 你反对使用另一个库,比如pandas?如果你把它变成pandas 格式,很多排序操作都会非常轻松。
  • csvfile 不是列表,是文件,所以无法排序。
  • @barny Python 中的文件对象是可迭代的,可以逐行生成文件内容,所以with open('test.txt') as f: sorted(f) 非常好
  • 是的,它是一个可迭代的行,而不是读取为 csv 的结果
  • @William 我刚刚在阅读有关 pandas (stackoverflow.com/questions/54911225/…) 的信息,但仍然可以使其工作。让我看看你写的答案

标签: python csv sorting datetime


【解决方案1】:

正如@barny 指出的那样,您需要有一个清单。同样正如@DeepSpace 指出的那样,您可以对迭代执行排序操作。

其他几个问题。排序仅适用于没有标题行(不包含日期)。所以我将其删除以测试以下内容。我还必须将您的日期格式字符串调整为 "%Y-%m-%d" 以匹配您的数据。

完全是这样:

with open('Empleados.csv', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=',')
    spamreader = sorted(spamreader, key=lambda x:datetime.strptime(x[4],"%Y-%m-%d"), reverse=True)

编辑:如果您也想干净利落地处理标题(而不是自己尝试学习练习),请使用以下内容。

with open('Empleados.csv', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=',')
    header = next(spamreader)
    spamreader = sorted(spamreader, key=lambda x:datetime.strptime(x[4],"%Y-%m-%d"), reverse=True)
    spamreader.insert(0, header)

【讨论】:

  • 你试过了吗?它不起作用,因为它试图将字符串 'FECHAINGRESO' 转换为日期
  • 是的,我试过了。你没有在我的帖子中看到我说我必须删除标题行吗?
  • ,,,这对 OP 没有帮助,因为他们的文件是带有标题的 csv 文件......这应该由代码处理,而不是通过修改输入文件使其无用
  • 当然有帮助。他们可以弄清楚如何填补空白。我们应该为他们做一切吗?这是一个学习网站。
  • 两个代码都运行良好。我更喜欢第二个,因为您不必更改数据/csv。谢谢
【解决方案2】:

如果您愿意使用外部库,最好的方法是使用pandas 的强大功能。这就是 pandas 的用途。

import pandas as pd
df = pd.read_csv('Empleados.csv')
df = df.sort_values('FECHAINGRESO', ascending=False)
df

# to save the sorted csv
df.to_csv('Empleados_sorted.csv')

【讨论】:

  • 刚刚试过这个并且有效,让我检查另一个答案
  • 我更改了 ascending=True 以使其按我想要的方式显示,但它工作得很好。谢谢
  • 完美!是的,这是我的首选方法,但如果你想避免导入熊猫,那么其他答案也可以。
  • 我不在乎使用 pandas,但因为它是“更简单”的另一种方式,我选择它作为答案,但这也是正确的。
猜你喜欢
  • 2014-07-06
  • 2018-04-14
  • 1970-01-01
  • 2010-09-26
  • 2018-09-02
  • 1970-01-01
  • 2010-12-18
  • 2020-02-12
  • 1970-01-01
相关资源
最近更新 更多