我正在尝试使用 Pandas/Numpy/Scipy 等在 Python 中进行一些最近邻类型分析,并尝试了几种不同的方法,我被难住了。

我有 2 个数据框,如下所示:

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 中的 2 个最近邻居(基于使用欧几里得距离的 Lon/Lat 值),然后将适当的 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)

这给了我 2 个最近邻居的距离和索引的列表,这很棒!但是我仍然有一些问题:
  • 我尝试使用 .isin 测试行 ['Type'] 列的类型列表成员资格,但这不起作用 - 有没有其他方法可以做到这一点?
  • 如何让 Pandas 为 kdtree 生成的 dist 和索引创建新列?
  • 另外,如何使用索引返回 Data-1 和 Data-2?

  • 提前致谢。

    最佳答案

    这很困惑,但我认为这可能是一个很好的起点。我使用了 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']]
    

    python - Python中的条件最近邻-LMLPHP

    关于python - Python中的条件最近邻,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33394238/

    10-12 20:25