【问题标题】:Distance Between Two Vectors As Columns Of Pandas DataFrame两个向量之间的距离作为 Pandas DataFrame 的列
【发布时间】:2019-08-07 13:40:45
【问题描述】:

我有一个 DataFrame,它有两个向量作为列。我想生成第三列,即两个向量之间的欧几里得距离。

我一直在使用 np.linalg.norm,但我收到了以下 ValueError:

ValueError: Length of values does not match length of index

以下是我的数据框:

Vectors clusterCenter
0   [-0.56663936, 0.8127105, -3.0935333, 1.2820396...   [-0.1343598546941601, 0.763419086816995, -1.48...
1   [-0.8221095, 1.3501785, -1.7770282, -0.4987612...   [-0.1343598546941601, 0.763419086816995, -1.48...
2   [-0.2715391, 1.1768106, -1.252441, 1.6287287, ...   [-0.1343598546941601, 0.763419086816995, -1.48...
3   [-0.58485925, -0.22501345, -0.9360838, 1.45915...   [-0.1343598546941601, 0.763419086816995, -1.48...
4   [-0.44443423, 1.0936267, -1.628864, 0.4971503,...   [-0.1343598546941601, 0.763419086816995, -1.48...

以下是错误/堆栈跟踪:

ValueError                                Traceback (most recent call last)
<ipython-input-181-f32674f361eb> in <module>
      4 #    profiles_to_cluster['distanceToCenter'][count] = np.linalg.norm(vectors[count]-
      5 #                                                                cluster_centers[i])
----> 6 profiles_to_cluster2['Distance'] = np.linalg.norm(profiles_to_cluster2['Vectors'] - profiles_to_cluster2['clusterCenter'])

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/frame.py in __setitem__(self, key, value)
   3368         else:
   3369             # set column
-> 3370             self._set_item(key, value)
   3371 
   3372     def _setitem_slice(self, key, value):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/frame.py in _set_item(self, key, value)
   3443 
   3444         self._ensure_valid_index(value)
-> 3445         value = self._sanitize_column(key, value)
   3446         NDFrame._set_item(self, key, value)
   3447 

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/frame.py in _sanitize_column(self, key, value, broadcast)
   3628 
   3629             # turn me into an ndarray
-> 3630             value = sanitize_index(value, self.index, copy=False)
   3631             if not isinstance(value, (np.ndarray, Index)):
   3632                 if isinstance(value, list) and len(value) > 0:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pandas/core/internals/construction.py in sanitize_index(data, index, copy)
    517 
    518     if len(data) != len(index):
--> 519         raise ValueError('Length of values does not match length of index')
    520 
    521     if isinstance(data, ABCIndexClass) and not copy:

ValueError: Length of values does not match length of index

【问题讨论】:

  • 什么代码返回错误?
  • 在上面添加了错误和堆栈跟踪。
  • 快速尝试表明np.linalg.norm 给出了列向量的范数,而不是行向量。

标签: python pandas euclidean-distance


【解决方案1】:

你可以这样做。

>>> x = pd.DataFrame(data=[[[1, 2, 3, 4], [4, 3, 2, 1]],
                          [[5, 6, 7, 8], [1, 2, 3, 4]]])

>>> (x[0].apply(np.array) - x[1].apply(np.array)).apply(np.linalg.norm)
0    4.472136
1    8.000000
dtype: float64

但是,您的数据格式和此方法是对 pandas 的滥用,它是为处理 panel data 而构建的,因此得名。我建议制作两个单独的数据框,每个数据框对于向量的每个维度都有一列。然后您可以简单地减去两个数据集并将np.linalg.norm 应用于每一行。像这样:

>>> # first column as separate DataFrame
>>> x = pd.DataFrame(data=[[1, 2, 3, 4], [5, 6, 7, 8]])
>>> # second column as separate DataFrame
>>> y = pd.DataFrame(data=[[4, 3, 2, 1], [1, 2, 3, 4]])
>>> np.linalg.norm(x - y, axis=1)
array([4.47213595, 8.        ])

【讨论】:

    猜你喜欢
    • 2020-05-17
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 2021-07-15
    相关资源
    最近更新 更多