gpt4 book ai didi

python - 如何更有效地遍历大型 CSV 文件?

转载 作者:行者123 更新时间:2023-11-28 22:11:06 25 4
gpt4 key购买 nike

我有许多大型 CSV 文件(每个大约有 200 万行),其中的时间戳行如下所示:

16.01.2019 12:52:22
16.01.2019 12:52:23
16.01.2019 12:52:24

鉴于每秒都有一个条目(大约一年的时间),应该可以理解为什么有这么多行。我想更灵活一些,所以我想把时间戳分为三行:日期,日期+小时,日期+小时+分钟,日期+小时+秒,这样我就可以随意对时间戳进行分组。我是这样做的:

dates = []
hours = []
minutes = []
seconds = []
i = 0


#initial values
dates.append(str(get_date(i).date()))
hours.append(str(get_date(i).hour))
minutes.append(str(get_date(i).minute))
seconds.append(str(get_date(i).second))

for i in range(len(df)):
if i < len(df) - 1 :
if str(get_date(i).date) < str(get_date(i+1).date): #dates: YYYY-MM-DD
dates.append(str(get_date(i+1).date()))
else:
dates.append(str(get_date(i).date()))

if str(get_date(i).hour) < str(get_date(i+1).hour): #dates+hours: YYYY-MM-DD HH
hours.append(str(get_date(i+1).date()) + " " + str(get_date(i+1).hour))
else:
hours.append(str(get_date(i).date()) + " " + str(get_date(i).hour))

if str(get_date(i).minute) < str(get_date(i+1).minute): #dates+hours+minutes: YYYY-MM-DD HH:mm
minutes.append(str(get_date(i+1).date()) + " " + str(get_date(i+1).hour) + ":" + str(get_date(i+1).minute))
else:
minutes.append(str(get_date(i).date()) + " " + str(get_date(i).hour) + ":" + str(get_date(i).minute))

if str(get_date(i).second) < str(get_date(i+1).second): #dates+hours+minutes+seconds: YYYY-MM-DD HH:mm+ss
seconds.append(str(get_date(i+1).date()) + " " + str(get_date(i+1).hour) + ":" + str(get_date(i+1).minute) + ":" + str(get_date(i+1).second))
else:
seconds.append(str(get_date(i).date()) + " " + str(get_date(i).hour) + ":" + str(get_date(i).minute) + ":" + str(get_date(i).second))


df["dates"] = dates
df["hours"] = hours
df["minutes"] = minutes
df["seconds"] = seconds

其中 get_date() 只是一个返回具有给定索引的时间戳的函数:

def get_date(i):
return (dt.datetime.strptime(df["timestamp"][i], '%d.%m.%Y %H:%M:%S'))

我基本上遍历所有条目,将每个日期/小时/分钟/秒放入列表中,然后将它们分别插入到我的数据框中。并将它们放入其中 get_date() 只是一个返回具有给定索引的时间戳的函数。

我想这会让我达到 O(n²)?这显然不理想。

现在,在一个 文件(约 60MB,200 万行)上执行此操作需要半小时。我个人想不出其他方法来做我想做的事情,所以我只是想看看是否有什么我可以做的来降低复杂性。

编辑:根据我的需要调整@Chris 的回答:

times = bogie_df["timestamp"]

#got an error when applying map directly into pd.DataFrame, which is why I first converted it into a list
items = ['year', 'month', 'day', 'hour', 'minute', 'second']
df = pd.DataFrame(list(map(operator.attrgetter(*items), pd.to_datetime(times))), columns=items)

#for my desired YYYY-MM-DD format (though attrgetter only return "1" for "January instead of "01"
df["date"] = df['year'].map(str) + "-" + df["month"].map(str) + df["day"].map(str)

最佳答案

operator.attrgetterpd.to_datetime 一起使用:

import pandas as pd
import operator

s = pd.Series(["16.01.2019 12:52:22",
"16.01.2019 12:52:23",
"16.01.2019 12:52:24"])

items = ['day', 'hour', 'minute', 'second']
df = pd.DataFrame(list(map(operator.attrgetter(*items), pd.to_datetime(s))), columns=items)

输出:

   day  hour  minute  second
0 16 12 52 22
1 16 12 52 23
2 16 12 52 24

基准:

large_s = pd.Series(pd.date_range('16.01.2019 12:52:22', periods=2000000, freq='1s').astype(str).tolist())
# Make 2M rows of timestamp in str

%%timeit

items = ['day', 'hour', 'minute', 'second']
df = pd.DataFrame(list(map(operator.attrgetter(*items), pd.to_datetime(large_s))), columns=items)
# 6.77 s ± 54.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

大约需要 7 秒。

更新:

不用手动创建 YYYY-mm-dd 格式的字符串,让 pandas 为您完成。

df = pd.DataFrame(pd.to_datetime(s), columns = ['date'])
items = ['year', 'month', 'day', 'hour', 'minute', 'second']
df[items] = pd.DataFrame(list(map(operator.attrgetter(*items), df['date'])), columns=items)

然后:

df['dates'] = df['date'].astype(str).str[:10]

输出(月份用零填充):

0    2019-01-16
1 2019-01-16
2 2019-01-16

关于python - 如何更有效地遍历大型 CSV 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56152230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com