python 使用大表循环的性能问题
python performance problems using loops with big tables
我正在使用 python 和 pandas 和 scipy 等多个库来准备数据,以便我可以开始更深入的分析。出于准备目的,我正在创建具有两个日期差异的新列。
我的代码提供了预期的结果,但速度非常慢,所以我无法将它用于具有 80K 行的 table。 运行 时间大约需要。 80分钟table就为了这个简单的操作
问题肯定和我的写操作有关:
tableContent[6]['p_test_Duration'].iloc[x] = difference
此外 python 提供警告:
日期差异的完整代码示例:
import time
from datetime import date, datetime
tableContent[6]['p_test_Duration'] = 0
#for x in range (0,len(tableContent[6]['p_test_Duration'])):
for x in range (0,1000):
p_test_ZEIT_ANFANG = datetime.strptime(tableContent[6]['p_test_ZEIT_ANFANG'].iloc[x], '%Y-%m-%d %H:%M:%S')
p_test_ZEIT_ENDE = datetime.strptime(tableContent[6]['p_test_ZEIT_ENDE'].iloc[x], '%Y-%m-%d %H:%M:%S')
difference = p_test_ZEIT_ENDE - p_test_ZEIT_ANFANG
tableContent[6]['p_test_Duration'].iloc[x] = difference
正确结果table:
去除循环,将函数应用于整个系列。
ZEIT_ANFANG = tableContent[6]['p_test_ZEIT_ANFANG'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S'))
ZEIT_ENDE = tableContent[6]['p_test_ZEIT_ENDE'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S'))
tableContent[6]['p_test_Duration'] = ZEIT_ENDE - ZEIT_ANFANG
您可以使用 pd.to_datetime
向量化日期的转换,避免不必要地使用 apply
。
tableContent[6]['p_test_Duration'] = (
pd.to_datetime(tableContent[6]['p_test_ZEIT_ENDE']) -
pd.to_datetime(tableContent[6]['p_test_ZEIT_ANFANG'])
)
此外,由于链式索引分配
,您收到了 SettingWithCopy
警告
tableContent[6]['p_test_Duration'].iloc[x] = difference
如果你按照我建议的方式去做,你就不用担心了。
其他答案都很好,但我建议您通常避免链式索引。 pandas 文档 explicitly discourage chained indexing 因为它产生不可靠的结果或速度很慢(由于多次调用 __getitem__)。假设您的数据框是多索引的,您可以替换:
tableContent[6]['p_test_Duration'].iloc[x] = difference
与:
tableContent.loc[x, (6, 'p_test_Duration')] = difference
你有时可以绕过这个问题,但为什么不学习最不可能在未来引起问题的方法呢?
我正在使用 python 和 pandas 和 scipy 等多个库来准备数据,以便我可以开始更深入的分析。出于准备目的,我正在创建具有两个日期差异的新列。
我的代码提供了预期的结果,但速度非常慢,所以我无法将它用于具有 80K 行的 table。 运行 时间大约需要。 80分钟table就为了这个简单的操作
问题肯定和我的写操作有关:
tableContent[6]['p_test_Duration'].iloc[x] = difference
此外 python 提供警告:
日期差异的完整代码示例:
import time
from datetime import date, datetime
tableContent[6]['p_test_Duration'] = 0
#for x in range (0,len(tableContent[6]['p_test_Duration'])):
for x in range (0,1000):
p_test_ZEIT_ANFANG = datetime.strptime(tableContent[6]['p_test_ZEIT_ANFANG'].iloc[x], '%Y-%m-%d %H:%M:%S')
p_test_ZEIT_ENDE = datetime.strptime(tableContent[6]['p_test_ZEIT_ENDE'].iloc[x], '%Y-%m-%d %H:%M:%S')
difference = p_test_ZEIT_ENDE - p_test_ZEIT_ANFANG
tableContent[6]['p_test_Duration'].iloc[x] = difference
正确结果table:
去除循环,将函数应用于整个系列。
ZEIT_ANFANG = tableContent[6]['p_test_ZEIT_ANFANG'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S'))
ZEIT_ENDE = tableContent[6]['p_test_ZEIT_ENDE'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S'))
tableContent[6]['p_test_Duration'] = ZEIT_ENDE - ZEIT_ANFANG
您可以使用 pd.to_datetime
向量化日期的转换,避免不必要地使用 apply
。
tableContent[6]['p_test_Duration'] = (
pd.to_datetime(tableContent[6]['p_test_ZEIT_ENDE']) -
pd.to_datetime(tableContent[6]['p_test_ZEIT_ANFANG'])
)
此外,由于链式索引分配
,您收到了SettingWithCopy
警告
tableContent[6]['p_test_Duration'].iloc[x] = difference
如果你按照我建议的方式去做,你就不用担心了。
其他答案都很好,但我建议您通常避免链式索引。 pandas 文档 explicitly discourage chained indexing 因为它产生不可靠的结果或速度很慢(由于多次调用 __getitem__)。假设您的数据框是多索引的,您可以替换:
tableContent[6]['p_test_Duration'].iloc[x] = difference
与:
tableContent.loc[x, (6, 'p_test_Duration')] = difference
你有时可以绕过这个问题,但为什么不学习最不可能在未来引起问题的方法呢?