bounty将在7天后过期。回答此问题可获得+100的声誉奖励。user1769197正在寻找来自声誉良好的来源的答案。
我有下面的函数,它接受一个形状为(20,000 x 20,000)。我必须运行函数20,000 x 20,000 = 400,000,000次。注意,indicator_Matrix
必须以Pandas Dataframe 的形式作为参数传递到函数中,因为我实际问题的 Dataframe 有timeIndex和integer列,但是为了理解问题,我稍微简化了一下。
Pandas实现
indicator_Matrix = pd.DataFrame(np.random.randint(0,2,[20000,20000]))
def operations(indicator_Matrix):
s = indicator_Matrix.sum(axis=1)
d = indicator_Matrix.div(s,axis=0)
res = d[d>0].mean(axis=0)
return res.iloc[-1]
我试着用numpy
来改进它,但它仍然需要很长时间才能运行。我也试过concurrent.future.ThreadPoolExecutor
,但它仍然需要很长时间才能运行,而且从列表理解方面没有太大的改进。
Numpy实现
indicator_Matrix = pd.DataFrame(np.random.randint(0,2,[20000,20000]))
def operations(indicator_Matrix):
s = indicator_Matrix.to_numpy().sum(axis=1)
d = (indicator_Matrix.to_numpy().T / s).T
d = pd.DataFrame(d, index = indicator_Matrix.index, columns = indicator_Matrix.columns)
res = d[d>0].mean(axis=0)
return res.iloc[-1]
output = [operations(indicator_Matrix) for i in range(0,20000**2)]
请注意,我再次将d
转换为 Dataframe 的原因是,我需要获得列均值,并使用.iloc[-1]
仅保留最后一列均值。d[d>0].mean(axis=0)
返回列均值,即
2478 1.0
0 1.0
**更新:**我仍然卡在这个问题上,我想知道在我的本地桌面上使用cudf
和CuPy
这样的gpu包是否会有什么不同。
1条答案
按热度按时间5lhxktic1#
你在做一些你不需要做的额外的数学运算。简单地英语,你在做的是:
1.对每列求和
1.“横向”旋转总和列表并在数组中进行划分
1.取每列的平均值,忽略零
1.仅返回最右边的均值
在第一步之后,除了最右边的列之外,您不再需要任何东西;你可以忽略剩下的。相应地修改你的代码:
......产生相同的结果,并且花费大约百分之一的时间。从较短的测试运行推断,这将在我的机器上运行4亿次的时间从大约114年减少到......大约324天。仍然不是很好。到目前为止,我还没有设法通过转换为NumPy、使用Numba编译或使用多处理来使它运行得更快,但我还是先把这个贴出来吧,万一有用的话
注意:您不太可能看到线程对像这样的计算密集型工作有任何改进;如果有的话,您会希望使用多处理。
concurrent.futures
为这两种类型都提供了执行器。线程在避免等待I/O方面非常有用。