Python中的条件最近邻算法

4

我将使用Pandas/Numpy/Scipy等工具,在Python中进行一些最近邻类型的分析。经过尝试了几种不同的方法后,我陷入困境。

我的数据包括两个如下所示的数据框:

df1

Lon1    Lat1    Type
10      10      A
50      50      A
20      20      B

df2

Lon2    Lat2    Type    Data-1  Data-2  
11      11      A       Eggs    Bacon       
51      51      A       Nuts    Bread   
61      61      A       Beef    Lamb    
21      21      B       Chips   Chicken
31      31      B       Sauce   Pasta
71      71      B       Rice    Oats
81      81      B       Beans   Peas

我试图基于经纬度的欧几里德距离确定df2中的两个最近邻居,并将相应的Data-1和Data-2值合并到df1中,使其看起来像这样:
Lon1    Lat1    Type    Data-1a     Data-2a     Data-1b     Data-2b
10      10      A       Eggs        Bacon       Nuts        Bread
50      50      A       Nuts        Bread       Beef        Lamb
20      20      B       Chips       Chicken     Sauce       Pasta

我尝试过长格式和宽格式方法,并倾向于使用scipy的ckd树,但是有没有办法只查看具有适当类型的行?
提前感谢。
**编辑**
我已经做了一些进展,如下所示:
Typelist = df2['Type'].unique().tolist()
df_dict = {'{}'.format(x): df2[(df2['Type'] == x)] for x in Rlist}

def treefunc(row):
    if row['Type'] == 'A':     
        type = row['Type']
        location = row[['Lon1','Lat1']].values
        tree = cKDTree(df_dict[type][['Lon2','Lat2']].values)
        dists, indexes = tree.query(location, k=2)
        return dists,indexes

dftest = df1.apply(treefunc,axis=1)

这让我得到了两个最近邻居的距离和索引列表,非常好!然而我仍然有一些问题:
  1. 我试图使用.isin测试row['Type']列是否为Typelist的成员,但这不起作用 - 还有其他方法可以做到这一点吗?

  2. 如何让Pandas为kdtree生成的距离和索引创建新的列?

  3. 还有,如何使用这些索引返回Data-1和Data-2?

谢谢你的帮助。

你如何在最后的数据框中获取 Data-1bData-2b 列? - under_the_sea_salad
如果这是第二近的邻居,那么对于第一行来说,这些列是错误的(应分别为“Chips”和“Chicken”)。 - under_the_sea_salad
它们是第二近邻的Data-1和Data-2列。 - Tom
薯条和鸡肉属于'B'类型,因此应该被忽略。我只想返回第一行中'A'类型的数据。 - Tom
1个回答

1
这很凌乱,但我认为这可能是一个不错的起点。我使用了scikit的实现,只是因为我更加熟悉(尽管我自己也是新手)。
import pandas as pd
from io import StringIO

s1 = StringIO(u'''Lon2,Lat2,Type,Data-1,Data-2
11,11,A,Eggs,Bacon
51,51,A,Nuts,Bread
61,61,A,Beef,Lamb
21,21,B,Chips,Chicken
31,31,B,Sauce,Pasta
71,71,B,Rice,Oats
81,81,B,Beans,Peas''')

df2 = pd.read_csv(s1)

#Start here

from sklearn.neighbors import NearestNeighbors
import numpy as np

dfNN = pd.DataFrame()

idx = 0
for i in pd.unique(df2.Type):
    dftype = df2[df2['Type'] == i].reindex()
    X = dftype[['Lon2','Lat2']].values
    nbrs = NearestNeighbors(n_neighbors=2, algorithm='kd_tree').fit(X)
    distances, indices = nbrs.kneighbors(X)
    for j in range(len(indices)):
        dfNN = dfNN.append(dftype.iloc[[indices[j][0]]])
        dfNN.loc[idx, 'Data-1b'] = dftype.iloc[[indices[j][1]]]['Data-1'].values[0]
        dfNN.loc[idx, 'Data-2b'] = dftype.iloc[[indices[j][1]]]['Data-2'].values[0]
        dfNN.loc[idx, 'Distance'] = distances[j][1]
        idx += 1
    dfNN = dfNN[['Lat2', 'Lon2', 'Type', 'Data-1', 'Data-2','Data-1b','Data-2b','Distance']]

enter image description here


还不确定如何合并df1。 - ryanmc
谢谢 - 我会看一下。我认为我们之间可能已经解决了这个问题! - Tom
不错 - 我已经添加了距离字段 - ryanmc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接