我试图调试一个慢速脚本,让自己对大熊猫不同操作的时机感到非常困惑。也许这个地方有很棒的文档,但我还没有找到它们。
我的测试脚本是:
import pandas as pd
import numpy as np
import datetime
# Set up simple timing.
times = []
labels = []
times.append(datetime.datetime.now())
# Build a dataframe.
df = pd.DataFrame(np.random.rand(20000,2), columns=['x', 'y'])
labels.append('Build DataFrame')
times.append(datetime.datetime.now())
# Filter the dataframe.
df = df[df.x > .5]
labels.append('Filter')
times.append(datetime.datetime.now())
# Rename some stuff.
df.rename(
columns={
'x': 'X',
'y': 'Y',
}, inplace=True, copy=False
)
labels.append('Rename columns')
times.append(datetime.datetime.now())
# Add a column.
df['n'] = 1
labels.append('Add column')
times.append(datetime.datetime.now())
print(df)
# Print out times in seconds.
print([labels[i] + ': ' + str((times[i + 1] - times[i]).total_seconds() * 1000.0)
for i in range(len(times) - 1)])
print('Total: ' + str((times[-1] - times[0]).total_seconds() * 1000.0))
这给了我时间:
['Build DataFrame: 1.19', 'Filter: 1.285',
'Rename columns: 16.884', 'Add column: 0.724']
Total: 20.083
如果我理解重命名,我不应该复制任何只是更新名称,所以应该几乎没时间说话。如果我重新安排好的事情,这就要诞生了。
['Build DataFrame: 1.613', 'Rename columns: 0.702',
'Filter: 2.664', 'Add column: 18.002']
Total: 22.981
然后看来,添加列正在占用所有时间。重新安排,我已经把一切都变得超级快了?
['Build DataFrame: 1.05', 'Rename columns: 0.364',
'Add column: 0.921', 'Filter: 1.52']
Total: 3.855
如果我添加另一列,这次使用df [' m'] = np.random.rand(df.shape [0])以便每个元素都有自己的值,我最终得到
['Build DataFrame: 1.015', 'Rename columns: 0.324',
'Add column: 0.473', 'Filter: 1.247', 'Add column: 18.497']
Total: 21.556
我可以通过在过滤器之前推送列添加来再次加快速度。
['Build DataFrame: 1.022', 'Rename columns: 0.439',
'Add column: 0.51', 'Add column: 0.58', 'Filter: 4.192']
Total: 6.743
显然,过滤和复制是这里唯一的昂贵操作,无论我做什么顺序,我都会得到一致的print(df)
输出。
我对这里发生的事情的猜测是,过滤器简单地存储了一个掩码,但实际上并没有强制复制,直到它必须。通过添加列我强制该副本。我不明白为什么重命名会强制复制。
有没有办法手动强制该副本进行测试?
更新表示完整性。 使用nitis`df =(df [df.X> .5])。copy()
['Build DataFrame: 0.989', 'Filter: 1.578', 'Rename columns: 0.362',
'Add column: 0.441']
Total: 3.37
顺便说一下,我的“科学性很强”'定时系统的测量误差约为1ms,因此在我关心的水平上。
答案 0 :(得分:1)
尝试替换
df = df[df.X > .5]
with,
df = (df[df.X > .5]).copy()