python - 如何减少这段代码的内存使用并提高其速度?
问题描述
我正在运行一个循环遍历pandas数据帧的所有行的for循环,然后它计算从一个点到数据帧中所有其他点的欧几里得距离,然后它通过下一点,并做同样的事情事情,等等。
问题是我需要存储距离的值计数以稍后绘制直方图,我将其存储在另一个熊猫数据框中。问题是随着第二个数据帧变大,我有时会耗尽内存。更不用说随着数据帧大小的增长,重复同样的循环会变得更慢,因为它会更重,更难在内存中处理。
这是一些重现原始问题的玩具数据:
import pandas as pd
xx = []
yy = []
tt = []
for i in progressbar(range(1,655556)):
xx.append(i)
yy.append(i)
tt.append(i)
df = pd.DataFrame()
df['xx'] = xx
df['yy'] = yy
df['tt'] = tt
df['xx'] = df['xx'].apply(lambda x : float(x))
df['yy'] = df['yy'].apply(lambda x : float(x))
df['tt'] = df['tt'].apply(lambda x : float(x))
df
这是我使用的原始代码:
counts = pd.DataFrame()
for index, row in df.iterrows():
dist = pd.Series(np.sqrt((row.xx - df.xx)**2 + (row.yy - df.yy)**2 + (row.tt - df.tt)**2))
counter = pd.Series(dist.value_counts( sort = True)).reset_index().rename(columns = {'index': 'values', 0:'counts'})
counts = counts.append(counter)
原始 df 的形状为 ,(695556, 3)
因此预期结果应该是一个形状的数据框,(695556**3, 2)
其中包含来自所有 3 个向量的所有距离值及其计数。问题是这不可能适合我的 16gb 内存。
所以我改为尝试这个:
for index, row in df.iterrows():
counts = pd.DataFrame()
dist = pd.Series(np.sqrt((row.xx - df.xx)**2 + (row.yy - combination.yy)**2 + (row.tt - df.tt)**2))
counter = pd.Series(dist.value_counts( sort = True)).reset_index().rename(columns = {'index': 'values', 0:'counts'})
counts = counts.append(counter)
counts.to_csv('counts/count_' + str(index) + '.csv')
del counts
在这个版本中,我不只是将计数数据帧存储到内存中,而是为每个循环编写一个 csv。这个想法是在完成后将它们放在一起。此代码比第一个代码运行得更快,因为每个循环的时间不会随着数据帧大小的增长而增加。虽然,它仍然很慢,因为它每次都必须写一个 csv。并不是说当我必须将所有这些 csv 读入单个数据帧时它会更慢。
谁能告诉我如何优化此代码以实现这些相同的结果,但以更快和更节省内存的方式?我也对其他实现持开放态度,例如 spark、dask 或任何实现相同结果的方式:包含所有距离的值的数据帧,但在时间和内存方面可能或多或少方便。
非常感谢您提前
解决方案
推荐阅读
- apache-kafka - Kafka Confluent Client .NET Core 无法访问 Windows 中间证书颁发机构
- c# - 如何从更新转移到功能
- javascript - 如何使用 ts-node 加载环境变量?
- macos - 尝试连接到 kafka 代理时出现 java.nio.BufferUnderflowException
- windows - Windows cmd 或 powershell 脚本,用于启动程序实例、获取其 PID 并在一段时间后停止它
- rest - 是否建议为内部服务创建 API?
- spring - Kotlin + Spring + JPA + Projections + 动态 SQL 语句
- javascript - 异步代码在 JavaScript 的底层是如何真正工作的?
- spring-integration - 自定义消息错误:消息因 XML 验证错误而被拒绝;嵌套异常是
- hive - 插入覆盖蜂巢表