【问题标题】:Faster way of converting Date column to weekday name in Pandas在 Pandas 中将日期列转换为工作日名称的更快方法
【发布时间】:2018-05-14 18:53:46
【问题描述】:

这是我通过 pd.read_csv() 读取的输入 csv 文件

ProductCode,Date,Receipt,Total
x1,07/29/15,101790,17.35
x2,07/29/15,103601,8.89
x3,07/29/15,103601,8.58
x4,07/30/15,101425,11.95
x5,07/29/15,101422,1.09
x6,07/29/15,101422,0.99
x7,07/29/15,101422,3
y7,08/05/15,100358,7.29
x8,08/05/15,100358,2.6
z3,08/05/15,100358,2.99


import pandas as pd
df = pd.read_csv('product.csv')

#I have to add some columns to the data:

df['Receipt_Count'] = df.groupby(['Date','Receipt'])['Receipt'].transform('count')
df['Day_of_Week'] = pd.to_datetime(df['Date']).dt.weekday_name

我的 csv 文件中有大约 800K 行。当我运行将日期转换为 weekday_name 的代码行时,大约需要 2 分钟。我知道我首先将我的“日期”列转换为日期时间,因为它被视为来自 csv 的字符串,然后它被转换为其工作日等价物。有什么办法可以缩短转化时间?

我对 Pandas/Python 还很陌生,所以我不确定我是否在这里遗漏了什么。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    指定日期字符串的格式将大大加快转换速度:

    df['Day_of_Week'] = pd.to_datetime(df['Date'], format='%m/%d/%y').dt.weekday_name
    

    以下是一些基准:

    import io
    import pandas as pd
    
    data = io.StringIO('''\
    ProductCode,Date,Receipt,Total
    x1,07/29/15,101790,17.35
    x2,07/29/15,103601,8.89
    x3,07/29/15,103601,8.58
    x4,07/30/15,101425,11.95
    x5,07/29/15,101422,1.09
    x6,07/29/15,101422,0.99
    x7,07/29/15,101422,3
    y7,08/05/15,100358,7.29
    x8,08/05/15,100358,2.6
    z3,08/05/15,100358,2.99
    ''')
    
    df = pd.read_csv(data)
    %timeit pd.to_datetime(df['Date']).dt.weekday_name
    # => 100 loops, best of 3: 2.48 ms per loop
    %timeit pd.to_datetime(df['Date'], format='%m/%d/%y').dt.weekday_name
    # => 1000 loops, best of 3: 507 µs per loop
    
    large_df = pd.concat([df] * 1000)
    %timeit pd.to_datetime(large_df['Date']).dt.weekday_name
    # => 1 loop, best of 3: 1.62 s per loop
    %timeit pd.to_datetime(large_df['Date'], format='%m/%d/%y').dt.weekday_name
    # => 10 loops, best of 3: 45.9 ms per loop
    

    即使对于您在 OP 中提供的小样本,性能也提高了 5 倍——对于更大的数据帧,它会变得非常非常好。

    【讨论】:

    • 指定日期字符串的格式就可以了。从将近 2 分钟的处理时间缩短到 2 秒,谢谢! %timeit pd.to_datetime(df['Date']).dt.weekday_name 1 个循环,最好的 3 个:每个循环 1 分钟 50 秒 %timeit pd.to_datetime(df['Date'], format='%m/%d/ %y').dt.weekday_name 1 个循环,最好的 3 个:每个循环 2.39 秒
    【解决方案2】:

    另一种方法是使用日期信息加载 csv,尤其是在您经常需要此日期列的情况下。不幸的是,似乎没有办法将日期格式传递给 infer_datetime_format 参数到 read_csv 似乎没有什么区别:

    import timeit
    
    repeat = 3
    numbers = 100
    
    setup = """import pandas as pd
    import io
    
    data = io.StringIO('''\
    ProductCode,Date,Receipt,Total
    ''' + '''\
    x1,07/29/15,101790,17.35
    x2,07/29/15,103601,8.89
    x3,07/29/15,103601,8.58
    x4,07/30/15,101425,11.95
    x5,07/29/15,101422,1.09
    x6,07/29/15,101422,0.99
    x7,07/29/15,101422,3
    y7,08/05/15,100358,7.29
    x8,08/05/15,100358,2.6
    z3,08/05/15,100358,2.99
    ''' * 100)"""
    
    
    def time(statement, _setup=None):
        print (min(
            timeit.Timer(statement, setup=_setup or setup).repeat(
                repeat, numbers)))
    
    time('pd.read_csv(data); data.seek(0)')
    time('pd.read_csv(data, parse_dates=["Date"]); data.seek(0)')
    time('pd.read_csv(data, parse_dates=["Date"],'
         'infer_datetime_format=True); data.seek(0)')
    

    打印:

    0.5536041843652657
    25.298157679942697
    25.34556727133409
    

    但是,如果您要经常使用 Date 列,则应该从一开始就对其进行转换。

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 2019-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-17
      • 2022-01-23
      相关资源
      最近更新 更多