处理“ read_csv”

时间:2019-03-20 10:10:30

标签: pandas

从时区偏移量更改(夏时制)的大型CSV文件中读取时,parse_dates变慢。您能建议我该如何处理吗?对于某些工作,我确实转换为“ UTC”,但我还需要使用原始的本地时间。有没有一种方法可以强制将列解析为datetime64[ns]而不是datetime64[ns, <offset>]?我认为增加列时间偏移量可能是一种改进https://github.com/pandas-dev/pandas/issues/16898。我可能需要原始的天真时间戳。

pd.__version__
'0.24.2'

时间偏移更改

import pandas as pd
from io import StringIO

data = StringIO("""date_time
2018-11-27 04:57:10+01:00
2018-11-27 04:57:10+02:00
2018-11-27 04:57:10+02:00
2018-11-27 04:57:10+02:00""")

df = pd.read_csv(data, sep=",", parse_dates =['date_time'])

输出

df.date_time

0    2018-11-27 04:57:10+01:00
1    2018-11-27 04:57:10+02:00
2    2018-11-27 04:57:10+02:00
3    2018-11-27 04:57:10+02:00
Name: date_time, dtype: object

我想我dtype: datetime64[ns]

没有时间偏移

import pandas as pd
from io import StringIO

data = StringIO("""date_time
2018-11-27 04:57:10+02:00
2018-11-27 04:57:10+02:00
2018-11-27 04:57:10+02:00
2018-11-27 04:57:10+02:00""")

df = pd.read_csv(data, sep=",", parse_dates =['date_time'])

输出

df.date_time

0   2018-11-27 04:57:10+02:00
1   2018-11-27 04:57:10+02:00
2   2018-11-27 04:57:10+02:00
3   2018-11-27 04:57:10+02:00
Name: date_time, dtype: datetime64[ns, pytz.FixedOffset(120)]

1 个答案:

答案 0 :(得分:1)

当您的数据在中间更改小时偏移量时,基于字符串的常规解析方法将简单地将这些偏移量更改中继为不同的未命名时区。 Pandas的问题在于它can't represent a column as containing more than one time zone,而不是将列表示为object。要解决此问题,我们需要将每个值显式转换为单个命名时区。这使Pandas可以使用datetime64[ns, America/New_York]作为列的类型,如果列中的所有值都具有相同的时区,它将自动执行。时区偏移量是由该时区定义定义的,因此信息得以保留。缺点是您必须知道命名时区才能与数据一起使用。

我已经尝试了几种方法来评估速度差异。无论出于何种原因,内置的Pandas函数to_datetime()都很慢。相反,我会根据您的数据建议一种替代方法,自己执行文本到日期时间的转换。以您喜欢的方式创建一个Python datetime对象,应用一个时区,然后转换为Pandas Timestamp类型。如果您对外部ciso8601库感到满意,该库具有从字符串到ISO8601的快速解析功能,则可以使用以下方法。您还需要流行的pytz库及其时区定义。

假设您有一个名为filename的CSV文件,并且其中有一个带有ISO8601时间戳记的Timestamp列。

import ciso8601
import pandas as pd
import pytz

TIME_ZONE = 'America/New_York'

def custom_parse(val):
    iso_time = ciso8601.parse_datetime(val)
    tz_time = iso_time.astimezone(pytz.timezone(TIME_ZONE))
    pd_time = pd.Timestamp(tz_time)
    return pd_time

dt = pd.read_csv(filename, parse_dates=['Timestamp'], date_parser=custom_parse)

如果您不想使用ciso8601,则可以将iso_time =步骤替换为基于正则表达式的解析步骤或datetime.datetime.strptime()等。几乎所有东西都比to_datetime()由熊猫提供。