在python 3.4.7的pool.map函数中添加额外的随机参数作为参数

在python 3.4.7的pool.map函数中添加额外的随机参数作为参数,python,pandas,numpy,python-multiprocessing,multiprocess,Python,Pandas,Numpy,Python Multiprocessing,Multiprocess,我想对大型数据集使用多处理来查找两列的乘积,并使用参数中的给定参数过滤数据集。我构建了一个测试集,但是我无法在这个测试集上进行多处理 首先,我尝试用parallelize_dataframe函数划分数据集,然后在subset_col函数中应用乘法函数和滤波函数。稍后,我将在parallelize_dataframe中追加完整的数据集 import numpy as np import pandas as pd from multiprocessing import Pool from multi

我想对大型数据集使用多处理来查找两列的乘积,并使用参数中的给定参数过滤数据集。我构建了一个测试集,但是我无法在这个测试集上进行多处理

首先,我尝试用parallelize_dataframe函数划分数据集,然后在subset_col函数中应用乘法函数和滤波函数。稍后,我将在parallelize_dataframe中追加完整的数据集

import numpy as np
import pandas as pd
from multiprocessing import Pool
from multiprocessing import Lock

df = pd.DataFrame({'col1': [1, 0, 1, 1, 1, 0, 0, 1, 0, 1],
                'col2': ['aa', 'aa', 'aa', 'bb', 'bb', 'bb', 'bb', 'cc', 'cc', 'cc'],
                'col3': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
                'col4': [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]})



def subset_col(df, p):
    print("Working with number: " + str(p))
    df[col5] = df[col3]*df[col4]
    df= df[df['col1'] == p]


def parallelize_dataframe(df, p, func, n_cores=80):
    df_split = np.array_split(df, n_cores)
    pool = Pool(n_cores)
    df = pd.concat(pool.map(func, df_split, p))
    pool.close()
    pool.join()
    return df


df3 = parallelize_dataframe(df,1,subset_col)


结果应该是col3和col4与col1的乘积,col1用一个值进行过滤。但我总是会犯这样的错误:

File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in parallelize_dataframe
struct.error: 'i' format requires -2147483648 <= number <= 2147483647 
文件“”,第1行,在
并行化_数据帧中的第4行文件“”
struct.error:“i”格式要求的官方文档为-2147483648,它“只支持一个iterable参数”。因此,您需要将
subset\u col
的接口改为使用单个参数。此外,您忘了创建列字符串,导致名称错误。要减少计算量,应在相乘之前进行过滤。然后应该返回一个值,除非函数仅通过副作用运行(我假设您不希望这样,因为您连接了池结果)

接下来,我们需要修复您如何调用
pool.map
,因为根据您所做的操作,它应该只接受两个参数(第三个,最后一个参数是chunksize)。由于您希望每个进程使用相同的
p
,因此我们将使用重复的
p
值将
dfs
压缩在一起。此外,考虑使用上下文管理器处理关闭资源。

def parallelize_dataframe(df, p, func, n_cores=None):
    if n_cores is None:
        n_cores = os.cpu_count()

    dfs = np.array_split(df, n_cores)
    pairs = zip(dfs, itertools.repeat(p))
    with Pool(n_cores) as pool:
        result = pool.map(func, pairs)

    df = pd.concat(result)
    return df
这将正确返回新的数据帧。但我肯定怀疑你有一台80核的机器。考虑使用<代码> NoCys= NON/<代码>以使用<代码> OS .CPUIO计数< /COD>

让您的机器上有多少个内核。
df3 = parallelize_dataframe(df, 1, subset_col)
根据您对
Pool.starmap
变体的请求:

def subset_col(df, p):
    # remove unpacking line
    ...

def parallelize_dataframe(df, p, func, n_cores=None):
    ...
    # change `pool.map(...)` to `pool.starmap(...)`
    ...

但是,您应该注意,
Pool
并没有为
starmap
提供
imap
imap\u无序
替代方案,这两个版本都是延迟评估版本,无论是否保留顺序都有所不同。

谢谢,Matt。我使用的是ec2实例,m5.24xlage。所以,我有大约96个内核可以使用。然而,我面临的问题是数据帧太大了,我必须找到一种实现多进程的方法,以尽可能减少实现时间。starmap不应该允许多个iterable参数吗。我经常使用R,并且熟悉foreach和doParallel。试图在python中发现类似的函数。我已经更新了上面关于
starmap
varaint的帖子。然而,对于这样一个大数据集,你可能想考虑使用其他工具而不是像熊猫那样。它的设计与Pandas具有类似的API,专门用于大型计算。
def subset_col(df, p):
    # remove unpacking line
    ...

def parallelize_dataframe(df, p, func, n_cores=None):
    ...
    # change `pool.map(...)` to `pool.starmap(...)`
    ...