【问题标题】:Finding euclidean distance from multiple mean vectors从多个平均向量中找到欧几里得距离
【发布时间】:2019-03-13 18:13:45
【问题描述】:

这就是我想要做的——我能够完成第 1 到第 4 步。在第 5 步之前需要帮助

基本上对于每个数据点,我想根据列 y 找到所有平均向量的欧几里得距离

  1. 获取数据
  2. 分离出非数字列
  3. 按 y 列查找平均向量
  4. 保存手段
  5. 根据 y 值从每一行中减去每个平均向量
  6. 每列平方
  7. 添加所有列
  8. 连接回数值数据集,然后连接非数值列
import pandas as pd

data = [['Alex',10,5,0],['Bob',12,4,1],['Clarke',13,6,0],['brke',15,1,0]]
df = pd.DataFrame(data,columns=['Name','Age','weight','class'],dtype=float)
print (df)
df_numeric=df.select_dtypes(include='number')#, exclude=None)[source]
df_non_numeric=df.select_dtypes(exclude='number')
means=df_numeric.groupby('class').mean()

对于means 的每一行,从df_numeric 的每一行中减去该行。然后取输出中每一列的平方,然后为每一行添加所有列。然后将此数据连接回df_numericdf_non_numeric

-------------更新1

添加代码如下。我的问题已经改变,更新的问题在最后。

def calculate_distance(row):
    return (np.sum(np.square(row-means.head(1)),1))

def calculate_distance2(row):
    return (np.sum(np.square(row-means.tail(1)),1))


df_numeric2=df_numeric.drop("class",1)
#np.sum(np.square(df_numeric2.head(1)-means.head(1)),1)
df_numeric2['distance0']= df_numeric.apply(calculate_distance, axis=1)
df_numeric2['distance1']= df_numeric.apply(calculate_distance2, axis=1)

print(df_numeric2)

final = pd.concat([df_non_numeric, df_numeric2], axis=1)
final["class"]=df["class"]

谁能确认这是实现结果的正确方法?我主要关心的是最后两个陈述。倒数第二个语句会正确连接吗?最后的语句会分配原始的class吗?我想确认 python 不会以随机顺序进行 concat 和类分配,并且 python 会保持行出现的顺序

final = pd.concat([df_non_numeric, df_numeric2], axis=1)
final["class"]=df["class"]

【问题讨论】:

  • 你试过df.set_index('Name', inplace=True)然后np.sqrt(np.abs(df.pow(2) - df.mean().pow(2)))当然是import numpy as np开头吗?
  • 能否提供完整的代码?

标签: python pandas euclidean-distance


【解决方案1】:

我想这就是你想要的

import pandas as pd
import numpy as np
data = [['Alex',10,5,0],['Bob',12,4,1],['Clarke',13,6,0],['brke',15,1,0]]
df = pd.DataFrame(data,columns=['Name','Age','weight','class'],dtype=float) 
print (df)
df_numeric=df.select_dtypes(include='number')#, exclude=None)[source]
# Make df_non_numeric a copy and not a view
df_non_numeric=df.select_dtypes(exclude='number').copy()

# Subtract mean (calculated using the transform function which preserves the 
# number of rows) for each class  to create distance to mean
df_dist_to_mean =  df_numeric[['Age', 'weight']] - df_numeric[['Age', 'weight', 'class']].groupby('class').transform('mean')
# Finally calculate the euclidean distance (hypotenuse)
df_non_numeric['euc_dist'] = np.hypot(df_dist_to_mean['Age'], df_dist_to_mean['weight'])
df_non_numeric['class'] = df_numeric['class']
# If you want a separate dataframe named 'final' with the end result
df_final = df_non_numeric.copy()
print(df_final)

也许可以写得更密集,但这样你会看到发生了什么。

【讨论】:

  • 嗨,我相信你更新的问题给你一个不正确的答案。我理解你的问题的方式是你想找到每个班级的平均值的距离。由于只有一个“1”类成员,显然距离应该为零。我相信您在calculate_distancecalculate_distance 中都减去了错误的平均值。但是,您最后的 concat 声明是正确的。
  • @user2543622 我的代码产生了正确的结果。我知道您想自己弄清楚并编写自己的代码。由于您不确定自己的结果,您可以使用我的结果来验证您自己的代码。
【解决方案2】:

我确信有更好的方法可以做到这一点,但我根据课程进行了迭代并遵循确切的步骤。

  1. 将“类”指定为索引。
  2. 旋转以使“类”位于列中。
  3. 执行与 df_numeric 对应的方法的操作
  4. 对值进行平方。
  5. 对行求和。
  6. 将数据帧连接在一起。

    data = [['Alex',10,5,0],['Bob',12,4,1],['Clarke',13,6,0],['brke',15,1,0]]
    df = pd.DataFrame(data,columns=['Name','Age','weight','class'],dtype=float)
    #print (df)
    
    
    df_numeric=df.select_dtypes(include='number')#, exclude=None)[source]
    df_non_numeric=df.select_dtypes(exclude='number')
    
    means=df_numeric.groupby('class').mean().T
    
    
    import numpy as np
    # Changed index 
    df_numeric.index = df_numeric['class']
    df_numeric.drop('class' , axis = 1 , inplace = True)
    
    # Rotated the Numeric data sideways so the class was in the columns
    df_numeric = df_numeric.T
    
    #Iterated through the values in means and seen which df_Numeric values matched
    store = [] # Assigned an empty array
    for j in means:
        sto = df_numeric[j]
        if type(sto) == type(pd.Series()): # If there is a single value it comes out as a pd.Series type
            sto = sto.to_frame() # Need to convert ot dataframe type
        store.append(sto-j) # append the various values to the array
    
    
    
    values = np.array(store)**2 # Squaring the values
    
    # Summing the rows
    summed = []
    for i in values:
        summed.append((i.sum(axis = 1)))
    
    
    
    df_new = pd.concat(summed , axis = 1)
    df_new.T
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    • 2013-04-07
    • 2018-11-02
    • 2021-02-11
    相关资源
    最近更新 更多