我有一个大型数据集(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))