【发布时间】:2022-06-12 02:33:04
【问题描述】:
我有一个y.csv 文件。文件大小为 10 MB,包含来自Jan 2020 to May 2020 的数据。
我每个月也有一个单独的文件。例如data-2020-01.csv。它包含详细的数据。每个月文件的文件大小在1 GB左右。
我将y.csv 按月份拆分,然后通过加载相关月份文件来处理数据。当我花了很多个月的时间时,这个过程花费的时间太长了。例如24 个月。
我想更快地处理数据。我可以访问具有 32 vCPU 和 128 GB 内存的 AWS m6i.8xlarge 实例。
我是多处理的新手。那么有人可以在这里指导我吗?
这是我当前的代码。
import pandas as pd
periods = [(2020, 1), (2020, 2), (2020, 3), (2020, 4), (2020, 5)]
y = pd.read_csv("y.csv", index_col=0, parse_dates=True).fillna(0) # Filesize: ~10 MB
def process(_month_df, _index):
idx = _month_df.index[_month_df.index.get_loc(_index, method='nearest')]
for _, value in _month_df.loc[idx:].itertuples():
up_delta = 200
down_delta = 200
up_value = value + up_delta
down_value = value - down_delta
if value > up_value:
y.loc[_index, "result"] = 1
return
if value < down_value:
y.loc[_index, "result"] = 0
return
for x in periods:
filename = "data-" + str(x[0]) + "-" + str(x[1]).zfill(2) # data-2020-01
filtered_y = y[(y.index.month == x[1]) & (y.index.year == x[0])] # Only get the current month records
month_df = pd.read_csv(f'{filename}.csv', index_col=0, parse_dates=True) # Filesize: ~1 GB (data-2020-01.csv)
for index, row in filtered_y.iterrows():
process(month_df, index)
【问题讨论】:
-
对同一主题感兴趣,遗憾的是还没有多进程经验,因此无法提供建议。只是一个观察,
.iterrows():的最后一个块正在大大减慢你的进程。 stackoverflow.com/a/65356169/8805842也调查那部分 -
这里的问题是您不能真正跨多个进程共享数据帧(由 y 引用)。它可以在多个线程之间共享,但这是一个有争议的问题,原因有两个:1)这是 CPU 绑定,所以多线程不合适 2)pandas 数据帧不是线程安全的
-
@NoobVB 因为我的
filtered_y很小,所以它不是这里的瓶颈。但是由于我这里只对索引感兴趣,所以我将它切换为itertuples。感谢您指出。 -
@LancelotduLac 我可以优化代码以不共享 y。我的 y 有唯一索引。
-
@John 请记住,10Mb 并不重要,对于 .iterrows() 或 itertuples(),行数是主要问题,所以只需检查您的 filters_y 的形状是否好奇.当然,请用你的 multiP 解决方案更新这个线程,-好奇 :)
标签: python python-3.x pandas multiprocessing