我可以征求一些关于Python列表的一般建议。我知道我不应该在这里回答“开放”的问题,但我担心会走错路。
我的问题是我有.csv文件,每个文件大约600,000行。 .csv的每一行都有6个字段,其中第一个字段是日期时间戳,格式为DD / MM / YYYY HH:MM:SS。接下来的两个字段为空,最后三个字段包含浮点和整数值,例如:
23/05/2017 16:42:17, , , 1.25545, 1.74733, 12
23/05/2017 16:42:20, , , 1.93741, 1.52387, 14
23/05/2017 16:42:23, , , 1.54875, 1.46258, 11
等
第1列(日期时间戳)中的两个值都不会相同。
我需要编写一个程序,对数据进行一些基本操作,例如:
我的问题是 - 如何处理数据?由于数据集的长度,我可能会遇到问题?
例如,我应该将所有数据导入到列表中,并且列表中的每个元素都是每行数据的子列表吗? E.g:
[[23/05/2017 16:42:17,'','', 1.25545, 1.74733, 12],[23/05/2017 16:42:20,'','', 1.93741, 1.52387, 14], ...]
或者最好将每个日期时间戳记作为字典中的“键”,并使字典“值”成为包含所有其他值的列表,例如:
{'23/05/2017 16:42:17': [ , , 1.25545, 1.74733, 12], ...}
等
如果我使用列表方法,是否有办法让Python在特定时间戳的第一列中“搜索”而不是在我们知道只有第一列时搜索600,000行乘以6列包含时间戳?
如果我的查询有点模糊,我很抱歉,但我很感激任何人都可以提供的任何指导。
答案 0 :(得分:2)
600000行不是很多,你的脚本应该可以使用列表或字典运行。
作为测试,让我们使用:
data = [["2017-05-02 17:28:24", 0.85260, 1.16218, 7],
["2017-05-04 05:40:07", 0.72118, 0.47710, 15],
["2017-05-07 19:27:53", 1.79476, 0.47496, 14],
["2017-05-09 01:57:10", 0.44123, 0.13711, 16],
["2017-05-11 07:22:57", 0.17481, 0.69468, 0],
["2017-05-12 10:11:01", 0.27553, 0.47834, 4],
["2017-05-15 05:20:36", 0.01719, 0.51249, 7],
["2017-05-17 14:01:13", 0.35977, 0.50052, 7],
["2017-05-17 22:05:33", 1.68628, 1.90881, 13],
["2017-05-18 14:44:14", 0.32217, 0.96715, 14],
["2017-05-18 20:24:23", 0.90819, 0.36773, 5],
["2017-05-21 12:15:20", 0.49456, 1.12508, 5],
["2017-05-22 07:46:18", 0.59015, 1.04352, 6],
["2017-05-26 01:49:38", 0.44455, 0.26669, 13],
["2017-05-26 18:55:24", 1.33678, 1.24181, 7]]
如果您正在寻找确切的时间戳,使用dict查找比使用列表要快得多。您必须确切知道自己在寻找什么:"23/05/2017 16:42:17"
的哈希值与"23/05/2017 16:42:18"
完全不同。
data_as_dict = {l[0]: l[1:] for l in data}
print(data_as_dict)
# {'2017-05-21 12:15:20': [0.49456, 1.12508, 5], '2017-05-18 14:44:14': [0.32217, 0.96715, 14], '2017-05-04 05:40:07': [0.72118, 0.4771, 15], '2017-05-26 01:49:38': [0.44455, 0.26669, 13], '2017-05-17 14:01:13': [0.35977, 0.50052, 7], '2017-05-15 05:20:36': [0.01719, 0.51249, 7], '2017-05-26 18:55:24': [1.33678, 1.24181, 7], '2017-05-07 19:27:53': [1.79476, 0.47496, 14], '2017-05-17 22:05:33': [1.68628, 1.90881, 13], '2017-05-02 17:28:24': [0.8526, 1.16218, 7], '2017-05-22 07:46:18': [0.59015, 1.04352, 6], '2017-05-11 07:22:57': [0.17481, 0.69468, 0], '2017-05-18 20:24:23': [0.90819, 0.36773, 5], '2017-05-12 10:11:01': [0.27553, 0.47834, 4], '2017-05-09 01:57:10': [0.44123, 0.13711, 16]}
print(data_as_dict.get('2017-05-17 14:01:13'))
# [0.35977, 0.50052, 7]
print(data_as_dict.get('2017-05-17 14:01:10'))
# None
请注意,您的DD/MM/YYYY HH:MM:SS
格式不太方便:按字典顺序排序单元格不会按日期时间对它们进行排序。您需要先使用datetime.strptime()
:
from datetime import datetime
data_as_dict = {datetime.strptime(l[0], '%Y-%m-%d %H:%M:%S'): l[1:] for l in data}
print(data_as_dict.get(datetime(2017,5,17,14,1,13)))
# [0.35977, 0.50052, 7]
print(data_as_dict.get(datetime(2017,5,17,14,1,10)))
# None
带有二进制搜索的如果您正在寻找时间戳范围,那么dict对您没什么帮助。
表示时间戳列表中的二进制搜索(例如bisect
)应该非常快。
import bisect
timestamps = [datetime.strptime(l[0], '%Y-%m-%d %H:%M:%S') for l in data]
i = bisect.bisect(timestamps, datetime(2017,5,17,14,1,10))
print(data[i-1])
# ['2017-05-15 05:20:36', 0.01719, 0.51249, 7]
print(data[i])
# ['2017-05-17 14:01:13', 0.35977, 0.50052, 7]
在重新发明轮子之前,您可能希望将所有CSV转储到一个小型数据库(sqlite,Postgresql,...)中并使用相应的查询。
如果您不希望增加数据库的复杂性,但又愿意花一些时间学习新语法,则应使用pandas.DataFrame
。它完全符合您的要求,然后是一些。