【问题标题】:A faster way to do these dataframe operations?执行这些数据帧操作的更快方法?
【发布时间】:2014-09-01 08:03:39
【问题描述】:

我正在从 csv 加载数据帧,然后执行以下操作。加载数据帧大约需要 2 秒。其他操作(主要是日期转换)需要 30 秒。有没有办法加快其他操作?

df = pd.DataFrame.from_csv( fn, index_col=None )

df['SCHEDULED_OFF'] = pd.to_datetime( df['SCHEDULED_OFF'], format='%d-%m-%Y %H:%M' )
df['LATEST_TAKEN'] = pd.to_datetime( df['LATEST_TAKEN'], format='%d-%m-%Y %H:%M:%S' )
df['FIRST_TAKEN'] = pd.to_datetime( df['FIRST_TAKEN'], format='%d-%m-%Y %H:%M:%S' )
df['SETTLED_DATE'] = pd.to_datetime( df['SETTLED_DATE'], format='%d-%m-%Y %H:%M:%S' )
df['ACTUAL_OFF'] = pd.to_datetime( df['ACTUAL_OFF'], format='%d-%m-%Y %H:%M:%S' )
df['ACTUAL_OFF'] = df['ACTUAL_OFF'].fillna( pd.datetime.min )
df[ 'LATEST_TAKEN_FROM_SCHEDULED_OFF' ] = ( df['SCHEDULED_OFF'].values -df['LATEST_TAKEN'].values ) / np.timedelta64( 1, 's' )
df[ 'FIRST_TAKEN_FROM_SCHEDULED_OFF' ] = ( df['SCHEDULED_OFF'].values -df['FIRST_TAKEN'].values ) / np.timedelta64( 1, 's' )
df[ 'IN_PLAY' ] = [ dicInPlay[ x ] for x in df[ 'IN_PLAY' ] ]
df['COUNTRY'] = df['COUNTRY'].fillna( '' )
df['FULL_DESCRIPTION'] = df['FULL_DESCRIPTION'].fillna( '' )
df['EVENT'] = df['EVENT'].fillna( '' )
df['COURSE'] = df['COURSE'].fillna( '' )

【问题讨论】:

  • 您是否尝试过告诉 csv 解析器哪些列是日期列,然后像这样创建 df? df = pd.read_csv( csv_path, parse_dates=['SCHEDULED_OFF','LATEST_TAKEN','FIRST_TAKEN','SETTLED_DATE','ACTUAL_OFF'])我觉得应该可以
  • 我刚刚敲了一个虚拟 csv,它可以毫无问题地处理所有不同的日期格式,所以试试我的建议
  • 感谢您的建议。刚试了一下,好像比原来的方法慢很多。;{
  • 更慢的是,您声称日期转换例程是最慢的部分,通过预先告诉 csv 解析器哪些列是日期以便解析它们,这应该更快
  • @EdChum 这不一定慢:read_csv 中的parse_dates 功能在许多情况下只是在后台使用to_datetime。速度将取决于日期格式。在这种情况下,需要dayfirst=True,这比在to_datetime 中提供格式要慢得多。

标签: python numpy pandas anaconda


【解决方案1】:

这不是一个真正的解决方案,但一种更快的方法是使用标准 ISO 格式的日期...

为了说明这可能会产生很大的不同,一些时间安排(一列包含 10000 个日期字符串):

# with standard ISO formatted strings (%Y-%m-%d %H:%M:%S)
In [52]: %timeit pd.to_datetime(df['date'])
100 loops, best of 3: 2.88 ms per loop

# with your dayfirst-like format (%d-%m-%Y %H:%M)
In [66]: %timeit pd.to_datetime(df['date'], format='%d-%m-%Y %H:%M')
10 loops, best of 3: 78.2 ms per loop

In [67]: %timeit pd.to_datetime(df['date'], dayfirst=True)
1 loops, best of 3: 800 ms per loop

所以我认为它慢的部分原因是这个日期解析(没有标准 ISO 格式时会慢 20-30 时间)。如果不能改变格式,我不知道这是否可以进一步增强。

对于其他行,我没有直接看到可能的加速,只有[ dicInPlay[ x ] for x in df[ 'IN_PLAY' ] ] 你可以测试df['IN_PLAY'].map(dicInPlay) 是否更快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 2021-03-06
    • 2022-11-28
    • 2019-01-29
    • 1970-01-01
    • 2021-04-10
    相关资源
    最近更新 更多