Python 分组依据/应用熊猫和多处理
我正在尝试使用多处理在熊猫数据帧上执行groupby和apply操作(希望加快代码的速度)。例如,如果我有如下数据帧:Python 分组依据/应用熊猫和多处理,python,pandas,python-multiprocessing,Python,Pandas,Python Multiprocessing,我正在尝试使用多处理在熊猫数据帧上执行groupby和apply操作(希望加快代码的速度)。例如,如果我有如下数据帧: A B C cluster_id 1 1 2 3 1 1 2 3 2 4 5 6 2 7 8 9 我想在列上应用一个函数,并根据cluster_id对它们进行分组 def my_func(x): return sum(x) 然
A B C
cluster_id
1 1 2 3
1 1 2 3
2 4 5 6
2 7 8 9
我想在列上应用一个函数,并根据cluster_id对它们进行分组
def my_func(x):
return sum(x)
然后,操作应产生:
A B C
cluster_id
1 2 4 6
2 11 13 15
有一些类似的帖子,所以,我确实设法接近某个地方,但还没有真正解决它。我的代码失败了,我不知道如何修复它。这就是我想到的
import multiprocessing as mp
import pandas as pd
import numpy as np
def _apply_df(args):
df, func = args
return df.groupby(level=0).apply(func)
def mp_apply(df, func):
workers = 4
pool = mp.Pool(processes=workers)
split_dfs = np.array_split(df, workers, axis=1)
result = pool.map(_apply_df, [(d, func) for d in split_dfs])
pool.close()
result = sorted(result, key=lambda x: x[0])
return pd.concat([i[1] for i in result])
def my_func(x):
return sum(x)
if __name__ == '__main__':
df = pd.DataFrame([[1, 2, 3, 1], [1, 2, 3, 1], [4, 5, 6, 2], [7, 8, 9, 2]], columns=['A', 'B', 'C', 'cluster_id'])
df = df.set_index('cluster_id')
out = mp_apply(df, my_func)
print(out)
我得到一个错误:
TypeError: unsupported operand type(s) for +: 'int' and 'str'
看起来它在线路上失败了
result = pool.map(_apply_df, [(d, func) for d in split_dfs])
传递到\u apply\u df
的参数d
看起来是空的
非常感谢您的帮助/想法。如果有必要的话,我正在使用Python3.6。谢谢 代码中出现问题的主要原因有两个
return pd.concat(result,axis=1)
现在,考虑到所使用的数据,代码将无问题运行
总体代码:
import multiprocessing as mp
import pandas as pd
import numpy as np
def _apply_df(args):
df, func = args
return df.groupby(level=0).apply(func)
def mp_apply(df, func):
workers = 4
pool = mp.Pool(processes=workers)
split_dfs = np.array_split(df, workers, axis=1)
result = pool.map(_apply_df, [(d, func) for d in split_dfs])
pool.close()
#result = sorted(result, key=lambda x: x[0])
return pd.concat(result,axis=1)
def my_func(x):
return x.sum()
if __name__ == '__main__':
df = pd.DataFrame([[1, 2, 3, 1], [1, 2, 3, 1], [4, 5, 6, 2], [7, 8, 9, 2]], columns=['A', 'B', 'C', 'cluster_id'])
df = df.set_index('cluster_id')
out = mp_apply(df, my_func)
print(out)
输出:
A B C
cluster_id
1 2 4 6
2 11 13 15
好东西!非常有用的评论。非常感谢你的帮助,这澄清了很多问题。遗憾的是,多重处理并没有让事情变得更快,因为某些原因,它现在运行得慢多了。我不知道,也许是腌制妨碍了你。不客气。请记住,熊猫的设计考虑到了性能。i、 e.它已经高度优化并利用了并行性。诀窍是有效地使用它。请尝试
out=df.groupby(level=0).sum()
。如何确保np.array\u split(df,workers,axis=1)
不会将属于同一组的行分割为不同的块?pd.concat(result,axis=1):当分组比超过100万时,性能会降低
import multiprocessing as mp
import pandas as pd
import numpy as np
def _apply_df(args):
df, func = args
return df.groupby(level=0).apply(func)
def mp_apply(df, func):
workers = 4
pool = mp.Pool(processes=workers)
split_dfs = np.array_split(df, workers, axis=1)
result = pool.map(_apply_df, [(d, func) for d in split_dfs])
pool.close()
#result = sorted(result, key=lambda x: x[0])
return pd.concat(result,axis=1)
def my_func(x):
return x.sum()
if __name__ == '__main__':
df = pd.DataFrame([[1, 2, 3, 1], [1, 2, 3, 1], [4, 5, 6, 2], [7, 8, 9, 2]], columns=['A', 'B', 'C', 'cluster_id'])
df = df.set_index('cluster_id')
out = mp_apply(df, my_func)
print(out)
A B C
cluster_id
1 2 4 6
2 11 13 15