Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 对数据帧中的唯一条目类别应用多处理的最有效方法是什么?_Python_Python 3.x_Pandas_Multiprocessing_Sklearn Pandas - Fatal编程技术网

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

Python 对数据帧中的唯一条目类别应用多处理的最有效方法是什么?,python,python-3.x,pandas,multiprocessing,sklearn-pandas,Python,Python 3.x,Pandas,Multiprocessing,Sklearn 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 总体目标是将

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

顺便说一句,
del catDF
完全没有意义。好吧,到目前为止,你赢得了今天的互联网!将我处理1.1 mil记录文件的时间从5.5小时减少到2分钟!非常值得赞赏的教训。