将多处理应用于 pandas 数据帧中唯一类别条目的最有效方法是什么?



我有一个大型数据集(tsv(,看起来像这样:

category     lat         lon  
apple        34.578967   120.232453  
apple        34.234646   120.535667  
pear         32.564566   120.453567  
peach        33.564567   121.456445  
apple        34.656757   120.423566  

总体目标是将包含单个类别的所有记录的数据帧传递给 DBScan 以生成群集标签,并使用多处理模块对所有类别执行此操作。 我可以让它工作,但我目前正在每个进程中重新加载整个数据集,以便子集到该类别,因为我在尝试将整个数据集引用为全局变量时继续收到错误。 代码如下所示:

import pandas as pd
from sklearn.cluster import DBSCAN
import multiprocessing as mp
def findClusters(inCat):
inTSV = r"C:trees.csv"
clDF = pd.read_csv(inTSV, sep='t')
catDF = clDF[clDF['category'] == 'inCat']
kms = 0.05
scaleDist = 0.01*kms
x = 'lon'
y = 'lat'
dbscan = DBSCAN(eps=scaleDist, min_samples=5)
clusters = dbscan.fit_predict(catDF[[x,y]])
catDF['cluster'] = clusters
catDF.to_csv(r"C:%s.csv" % (inCat))
del catDF
if __name__ == "__main__":
inTSV = r"C:trees.csv"
df = pd.read_csv(inTSV, sep='t')
catList = list(df.category.unique())
cores = mp.cpu_count()
pool = mp.Pool(cores - 1)
pool.map(findClusters, catList)
pool.close()
pool.join()

我知道这不是最有效的方法,因为我正在重读并写出中间文件。 我想并行运行每类数据的聚类。 是否可以生成为多处理池提供数据帧(每个类别一个(的列表? 这些在处理后如何被捕获(包装在 concat 调用中? 有没有更好的方法将数据加载到内存中一次,并让每个进程能够访问它以切出它需要的类别数据,如何?

运行 Anaconda,Python 3.5.5

感谢您的任何见解。

您可以使用df.groupby,所以请注意:

In [1]: import pandas as pd
In [2]: df = pd.read_clipboard()
In [3]: df
Out[3]:
category        lat         lon
0    apple  34.578967  120.232453
1    apple  34.234646  120.535667
2     pear  32.564566  120.453567
3    peach  33.564567  121.456445
4    apple  34.656757  120.423566
In [4]: list(df.groupby('category'))
Out[4]:
[('apple',   category        lat         lon
0    apple  34.578967  120.232453
1    apple  34.234646  120.535667
4    apple  34.656757  120.423566),
('peach',   category        lat         lon
3    peach  33.564567  121.456445),
('pear',   category        lat         lon
2     pear  32.564566  120.453567)]

只需重写你的函数以期望一对,如下所示:

def find_clusters(grouped):
cat, catDF = grouped
kms = 0.05
scale_dist = 0.01*kms
x = 'lon'
y = 'lat'
dbscan = DBSCAN(eps=scale_dist, min_samples=5)
clusters = dbscan.fit_predict(catDF[[x,y]])
catDF['cluster'] = clusters
catDF.to_csv(r"C:%s.csv" % (cat))

老实说,我认为写入中间文件很好。

如果没有,您可以随时执行以下操作:

return catDF

而不是

catDF.to_csv(r"C:%s.csv" % (cat))

然后:

df = pd.concat(pool.map(findClusters, catList))

相关内容

最新更新