我在pandas issues报告了这个问题.
与此同时,我发布此处希望节省其他时间,以防他们遇到类似的问题.
在分析需要优化的进程时,我发现重命名列不在适当位置可以提高x120的性能(执行时间).
分析表明这与垃圾收集有关(见下文).
以下简短示例演示了因子x12:
import pandas as pd
import numpy as np
就地=真
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
df = (df1-df2).dropna()
## inplace rename:
df.rename(columns={col:'d{}'.format(col) for col in df.columns}, inplace=True)
100 loops, best of 3: 15.6 ms per loop
ncalls tottime percall cumtime percall filename:lineno(function)
06002
就地=假
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
df = (df1-df2).dropna()
## avoid inplace:
df = df.rename(columns={col:'d{}'.format(col) for col in df.columns})
1000 loops, best of 3: 1.24 ms per loop
避免拉网
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
#no dropna:
df = (df1-df2)#.dropna()
## inplace rename:
df.rename(columns={col:'d{}'.format(col) for col in df.columns}, inplace=True)
1000 loops, best of 3: 865 µs per loop
%%timeit
np.random.seed(0)
r,c = (7,3)
t = np.random.rand(r)
df1 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
indx = np.random.choice(range(r),r/3, replace=False)
t[indx] = np.random.rand(len(indx))
df2 = pd.DataFrame(np.random.rand(r,c), columns=range(c), index=t)
## no dropna
df = (df1-df2)#.dropna()
## avoid inplace:
df = df.rename(columns={col:'d{}'.format(col) for col in df.columns})
1000 loops, best of 3: 902 µs per loop
解决方法:
这是关于github的解释的副本.
无法保证现场操作实际上更快.通常它们实际上是在副本上运行的相同操作,但是重新分配了顶级引用.
(df1-df2).dropna()调用会创建数据帧的切片.应用新操作时,会触发SettingWithcopy检查,因为它可能是副本(但通常不是).
此检查必须执行垃圾收集以清除某些缓存引用以查看它是否为副本.不幸的是,Python语法使这不可避免.
你不能通过简单地制作副本来实现这一点.
df = (df1-df2).dropna().copy()
其次是就地操作将像以前一样高效.
我的个人意见:我从不使用就地操作.语法更难阅读,它没有任何优势.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。