与熊猫成对的欧几里得距离忽略了NaNs

时间:2018-07-15 22:32:20

标签: python pandas numpy dataframe euclidean-distance

我从字典开始,这是我的数据已经被格式化的方式:

import pandas as pd
dict2 = {'A': {'a':1.0, 'b':2.0, 'd':4.0}, 'B':{'a':2.0, 'c':2.0, 'd':5.0}, 
'C':{'b':1.0,'c':2.0, 'd':4.0}}

然后我将其转换为熊猫数据框:

df = pd.DataFrame(dict2)
print(df)
     A    B    C
a  1.0  2.0  NaN
b  2.0  NaN  1.0
c  NaN  2.0  2.0
d  4.0  5.0  4.0

当然,我可以通过这样做一次获得一个差异:

df['A'] - df['B']
Out[643]: 
a   -1.0
b    NaN
c    NaN
d   -1.0
dtype: float64

我想出了如何遍历和计算A-A,A-B,A-C:

for column in df:
print(df['A'] - df[column])

a    0.0
b    0.0
c    NaN
d    0.0
Name: A, dtype: float64
a   -1.0
b    NaN
c    NaN
d   -1.0
dtype: float64
a    NaN
b    1.0
c    NaN
d    0.0
dtype: float64

我想做的是遍历各列,以便计算| A-B |,| A-C |和| B-C |。并将结果存储在另一本词典中。

我想这样做是为了稍后计算列的所有组合之间的欧几里得距离。如果有更简单的方法可以做到这一点,我也希望看到它。谢谢。

2 个答案:

答案 0 :(得分:4)

您可以使用numpy广播来计算向量化的欧几里得距离(L2-范数),而无需使用np.nansum来计算NaN。

i = df.values.T
j = np.nansum((i - i[:, None]) ** 2, axis=2) ** .5

如果您想要一个表示距离矩阵的DataFrame,则如下所示:

df = (lambda v, c: pd.DataFrame(v, c, c))(j, df.columns)
df
          A         B    C
A  0.000000  1.414214  1.0
B  1.414214  0.000000  1.0
C  1.000000  1.000000  0.0

df[i, j]表示原始DataFrame中第i 和第j th 列之间的距离。

答案 1 :(得分:2)

下面的code遍历各列以计算差异。

# Import libraries
import pandas as pd
import numpy as np

# Create dataframe
df = pd.DataFrame({'A': {'a':1.0, 'b':2.0, 'd':4.0}, 'B':{'a':2.0, 'c':2.0, 'd':5.0},'C':{'b':1.0,'c':2.0, 'd':4.0}})
df2 = pd.DataFrame()

# Calculate difference
clist = df.columns
for i in range (0,len(clist)-1):
    for j in range (1,len(clist)):
        if (clist[i] != clist[j]):
            var = clist[i] + '-' + clist[j]
            df[var] = abs(df[clist[i]] - df[clist[j]]) # optional
            df2[var] = abs(df[clist[i]] - df[clist[j]]) # optional

在相同数据框中输出

df.head()

enter image description here

在新数据框中输出

df2.head()

enter image description here