【问题标题】:For loop only returning last itemFor循环仅返回最后一项
【发布时间】:2021-08-14 01:24:27
【问题描述】:
# Create random df
df = pd.DataFrame(np.random.randint(1,10, size=(100,23)))
test = df[:50]  

for i in range(len(test)):
    query_node = test.iloc[i]
    # Find the distance between this node and everyone else
    euclidean_distances = test.apply(lambda row: distance.euclidean(row, query_node), axis=1)
    # Create a new dataframe with distances.
    distance_frame = pd.DataFrame(data={"dist": euclidean_distances, "idx": euclidean_distances.index})
    distance_frame.sort_values("dist", inplace=True)
    smallest_dist = [dist["idx"] for idx, dist in distance_frame.iloc[1:4].iterrows()]

我被这个问题难住了,想知道是否有人能看出我哪里出错了。我正在尝试计算每行与每行之间的欧几里得距离。然后,我对这些距离进行排序,并按列表 minimum_dist 中的最小距离返回“最相似”行的索引位置。

问题是这只返回最后一行最相似的索引位置:[6.0, 3.0, 4.0]

我想要的输出是这样的:

Original ID Matches
1 4,5,6
2 8,2,5

我试过了,但结果是一样的:

list_of_mins = []

for i in range(len(test)):
    query_node = test.iloc[i]
    # Find the distance between this node and everyone else
    euclidean_distances = test.apply(lambda row: distance.euclidean(row, query_node), axis=1)
    # Create a new dataframe with distances.
    distance_frame = pd.DataFrame(data={"dist": euclidean_distances, "idx": euclidean_distances.index})
    distance_frame.sort_values("dist", inplace=True)
    smallest_dist = [dist["idx"] for idx, dist in distance_frame.iloc[1:4].iterrows()]
    for i in range(len(test)):
        list_of_mins.append(smallest_dist_ixs)

Does anyone know what's causing this problem? thank you!

【问题讨论】:

    标签: python pandas list loops


    【解决方案1】:

    如果您尝试在数据框中或(为了方便测试)字典中返回结果,会发生什么情况?例如:

    df = pd.DataFrame(np.random.randint(1,10, size=(100,23)))
    test = df[:50]
    closest_nodes = {}
    
    for i in range(len(test)):
        query_node = test.iloc[i]
        # Find the distance between this node and everyone else
        euclidean_distances = test.apply(lambda row: distance.euclidean(row, query_node), axis=1)
        # Create a new dataframe with distances.
        distance_frame = pd.DataFrame(data={"dist": euclidean_distances, "idx": euclidean_distances.index})
        distance_frame.sort_values("dist", inplace=True)
        closest_nodes[i] = [dist["idx"] for idx, dist in distance_frame.iloc[1:4].iterrows()]
    

    我在您的代码中没有看到的是某种存储操作,可以将每个测试用例的一个结果放入永久结构中。

    【讨论】:

    • 您好,感谢您的回复 - 这也很有效,非常适合我的代码!
    【解决方案2】:

    我没有可用的距离库,所以我将其更改为一个简单的总和,但在将其替换回距离后它应该可以工作

    import pandas as pd
    import numpy as np
    
    df = pd.DataFrame(np.random.randint(1, 10, size=(100, 23)))
    test = df[:50]
    
    dict_results = {'ids': [],
                    'ids_min': []}
    
    n_min = 2
    
    for i in range(len(test)):
        query_node = test.iloc[i]
        # Find the distance between this node and everyone else
        euclidean_distances = test.apply(lambda row: np.sum(row), axis=1)
        # Create a new dataframe with distances.
        # print(euclidean_distances)
        distance_frame = pd.DataFrame(data={"dist": euclidean_distances,
                                            "idx": euclidean_distances.index})
    
        selected_min = distance_frame.sort_values("dist").head(n_min)
        dict_results['ids'].append(i)
        dict_results['ids_min'].append(', '.join(selected_min['idx'].astype('str')))
    
    print(pd.DataFrame(dict_results))
    

    我对您的代码添加了一些更改:

    1. 添加了n_min 参数来定义第二列中需要多少元素(到最近行的索引数)
    2. 创建了一个用来保存结果的字典,以创建您想要的数据框。
    3. 在循环中添加了 append 以将每次迭代的结果添加到保存结果的字典中
    4. 在循环之后,如果您在 pd.DataFrame 中调用 dict,它将按照与 distance_frame 相同的方式进行解析

    【讨论】:

    • 嗨!这帮助很大,谢谢!效果很好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    • 2018-06-05
    • 1970-01-01
    相关资源
    最近更新 更多