【问题标题】:Use KDTree/KNN Return Closest Neighbors使用 KDTree/KNN 返回最近的邻居
【发布时间】:2019-12-24 21:02:41
【问题描述】:

我有两个 python pandas 数据框。一个包含自 2007 年以来所有 NFL 四分卫的大学橄榄球统计数据以及他们的球员类型(精英、平均、低于平均水平)的标签。另一个数据框包含本赛季所有大学橄榄球队的数据以及预测标签。

我想进行某种分析,根据标签确定每个大学橄榄球 qb 的两个最接近的 NFL 比较。我想将两个可比较的 qbs 添加为第二个数据框的两个新列。

两个数据框中的特征名称相同。以下是数据框的样子:

Player     Year    Team    GP    Comp %   YDS    TD   INT     Label
Player A   2020     ASU    12     65.5    3053   25    6     Average

对于上面的示例,我希望两个找到最接近玩家 A 的两个邻居,它们也具有来自第一个数据帧的标签“平均”。 我想这样做的方法是使用 Scipy 的 KDTree 并运行查询树:

tree = KDTree(nfl[features], leafsize=nfl[features].shape[0]+1)
closest = []

for row in college.iterrows():
    distances, ndx = tree.query(row[features], k=2)
    closest.append(ndx)
print(closest)

但是,打印语句返回了一个空列表。这是解决我的问题的正确方法吗?

【问题讨论】:

    标签: python-3.x pandas scipy knn kdtree


    【解决方案1】:

    .iterrows(),将返回 namedtuples (index, Series) 其中 index 显然是行的索引,而 Series 是特征值,其索引是列名(见下文)。

    正如你所拥有的那样,row 被存储为那个元组,所以当你拥有 row[features] 时,它不会真正做任何事情。您真正追求的是具有特征和价值的系列,即row[1]。因此,您可以直接调用它,也可以通过 for idx, row in df.iterrows(): 在循环中将它们分解。然后你就可以打电话给那个系列row

    Scikit learn 是一个很好的软件包(实际上是基于 Scipy 构建的,因此您会注意到相同的语法)。您必须根据您的规范编辑代码(例如过滤器以仅具有“平均”播放器,也许您正在对类别列进行一次性编码,在这种情况下可能需要将其添加到功能中等),但是为了给你一个想法(我编造这些数据框只是为了举例......实际上 nfl 是准确的,但学院完全编造了),你可以在下面看到使用 kdtree 然后取@中的每一行987654329@ 数据帧以查看它最接近nfl 数据帧中的哪两个值。我显然让它打印出名称,但正如您在print(closest) 中看到的那样,原始数组就在那里。

    import pandas as pd
    
    nfl = pd.DataFrame([['Tom Brady','1999','Michigan',11,61.0,2217,16,6,'Average'],
                       ['Aaron Rodgers','2004','California',12,66.1,2566,24,8,'Average'],
                       ['Payton Manning','1997','Tennessee',12,60.2,3819,36,11,'Average'],
                       ['Drew Brees','2000','Perdue',12,60.4,3668,26,12,'Average'],
                       ['Dan Marino','1982','Pitt',12,58.5,2432,17,23,'Average'],
                       ['Joe Montana','1978','Notre Dame',11,54.2,2010,10,9,'Average']],
                        columns = ['Player','Year','Team','GP','Comp %','YDS','TD','INT','Label'])
    
    
    college = pd.DataFrame([['Joe Smith','2019','Illinois',11,55.6,1045,15,7,'Average'],
                       ['Mike Thomas','2019','Wisconsin',11,67,2045,19,11,'Average'],
                       ['Steve Johnson','2019','Nebraska',12,57.3,2345,9,19,'Average']],
                        columns = ['Player','Year','Team','GP','Comp %','YDS','TD','INT','Label'])
    
    
    features = ['GP','Comp %','YDS','TD','INT']
    
    from sklearn.neighbors import KDTree
    tree = KDTree(nfl[features], leaf_size=nfl[features].shape[0]+1)
    closest = []
    
    for idx, row in college.iterrows():
    
        X = row[features].values.reshape(1, -1)
        distances, ndx = tree.query(X, k=2, return_distance=True)
        closest.append(ndx)
    
        collegePlayer = college.loc[idx,'Player']
        closestPlayers = [ nfl.loc[x,'Player'] for x in ndx[0] ]
    
        print ('%s closest to: %s' %(collegePlayer, closestPlayers))
    
    print(closest)
    

    输出:

    Joe Smith closest to: ['Joe Montana', 'Tom Brady']
    Mike Thomas closest to: ['Joe Montana', 'Tom Brady']
    Steve Johnson closest to: ['Dan Marino', 'Tom Brady']
    

    【讨论】:

      猜你喜欢
      • 2018-06-16
      • 1970-01-01
      • 2018-06-09
      • 2017-12-11
      • 1970-01-01
      • 1970-01-01
      • 2020-06-17
      • 2018-04-04
      • 2018-04-11
      相关资源
      最近更新 更多