python - Pandas 优化两列上的日期时间比较

标签 python pandas performance dataframe

如何优化以下操作:

df[(df.start <= x) & (df.end >= y)]

我尝试使用 MultiIndex 但没有看到明显的加速。

df = df.set_index(['start', 'end'])
df[(df.index.get_level_values('start') <= end) & (discon_df.index.get_level_values('end') >= start)]

示例数据:

'<table border="1" class="dataframe">\n  <thead>\n    <tr style="text-align: right;">\n      <th></th>\n      <th>start</th>\n      <th>end</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>2018-11-13 10:28:30.304287</td>\n      <td>2018-11-13 10:46:28.663868</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>2018-11-13 12:27:32.226550</td>\n      <td>2018-11-13 13:09:02.723869</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>2018-11-13 13:29:29.981659</td>\n      <td>2018-11-13 13:54:01.138963</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>2018-11-13 14:30:49.380554</td>\n      <td>2018-11-13 14:48:50.627830</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>2018-11-13 14:59:26.799017</td>\n      <td>2018-11-13 15:24:00.453983</td>\n    </tr>\n    <tr>\n      <th>5</th>\n      <td>2018-11-13 16:30:16.824188</td>\n      <td>2018-11-13 16:48:35.346318</td>\n    </tr>\n    <tr>\n      <th>6</th>\n      <td>2018-11-13 17:15:25.486287</td>\n      <td>2018-11-13 17:59:30.774629</td>\n    </tr>\n    <tr>\n      <th>7</th>\n      <td>2018-11-13 18:27:41.915379</td>\n      <td>2018-11-13 18:47:26.528320</td>\n    </tr>\n    <tr>\n      <th>8</th>\n      <td>2018-11-13 19:28:12.835576</td>\n      <td>2018-11-13 19:52:15.448146</td>\n    </tr>\n    <tr>\n      <th>9</th>\n      <td>2018-11-13 20:41:41.210849</td>\n      <td>2018-11-13 21:07:52.249831</td>\n    </tr>\n    <tr>\n      <th>10</th>\n      <td>2018-11-13 21:11:23.529623</td>\n      <td>2018-11-13 21:42:10.106951</td>\n    </tr>\n  </tbody>\n</table>'

最佳答案

瓶颈是用于索引的 bool 系列/数组的构造。

降级到 NumPy 似乎可以带来合理的(~2 倍)性能提升。查看相关:pd.Timestamp versus np.datetime64: are they interchangeable for selected uses?

# boundaries for testing
mindt = pd.to_datetime('2016-01-01') 
maxdt = pd.to_datetime('2017-01-01')

x = ((df['start'] <= mindt) & (df['end'] >= maxdt)).values
y = (df['start'].values <= mindt.to_datetime64()) & (df['end'].values >= maxdt.to_datetime64())

# check results are the same
assert np.array_equal(x, y)

%timeit (df['start'].values <= mindt.to_datetime64()) & (df['end'].values >= maxdt.to_datetime64())
# 55.6 ms per loop

%timeit (df['start'] <= mindt) & (df['end'] >= maxdt)
# 108 ms per loop

设置

np.random.seed(0)

def random_dates(start, end, n):
    start_u = start.value//10**9
    end_u = end.value//10**9
    cols = ['start', 'end']
    df = pd.DataFrame({col: pd.to_datetime(np.random.randint(start_u, end_u, n), unit='s') for col in cols})
    df = pd.DataFrame(np.sort(df.values, axis=1), columns=cols)
    df[cols] = df[cols].apply(pd.to_datetime, errors='raise')
    return df

# construct a dataframe of random dates
df = random_dates(pd.to_datetime('2015-01-01'), pd.to_datetime('2018-01-01'), 10**7)

关于python - Pandas 优化两列上的日期时间比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53446171/

相关文章:

python - 在 Python 中使用正则表达式删除数据框的部分列名

java - 在单核系统上拥有多个线程还能提高性能吗?

python - 更 Pythonic 的方式 - Pandas 数据帧操作

Python - 通过 SSH 读取二进制文件

python - Ansible:json 对象上的 set_fact

python - Numpy 中的逻辑索引与 MATLAB 中的两个索引

python - PIL : draw transparent text on top of an image

python - Seaborn 显示条形图时出错

python - 如何绘制每组的直方图子图

java - 将 Guava.Preconditions 与串联字符串一起使用时是否会对性能产生影响?