【问题标题】:Group people which have different locations将具有不同位置的人分组
【发布时间】:2020-06-26 23:21:37
【问题描述】:

我需要帮助。我将人们分组的功能并没有真正起作用。问题很简单:

我有一个包含以下列的数据框:

  • 纬度
  • 经度
  • 地板

这些列是人的随机位置。 数据帧的长度是 9 的倍数(在本例中长度为 36。我实际上要长得多)。

我想按照以下想法对人们进行分组:

首先,我创建一个名为“组”的新列。 住在一起的人(根据坐标)被分配到一个特定的组号(1、2 3、...)。每组包含 3 人。

现在是棘手的部分:坐标相同的人不能在同一组中

我就是这样做的:

这是数据:

array_data=([[ 50.56419  ,   8.67667  ,   2.       , 160.       ],
   [ 50.5643136,   8.6772816,   3.       ,  89.       ],
   [ 50.5646274,   8.6763909,   0.       , 259.       ],
   [ 50.5661047,   8.6765931,   1.       , 100.       ],
   [ 50.5663442,   8.6575205,   1.       , 117.       ],
   [ 50.56686  ,   8.67598  ,   1.       ,  95.       ],
   [ 50.56747  ,   8.67604  ,   2.       , 199.       ],
   [ 50.56762  ,   8.6702799,   0.       , 148.       ],
   [ 50.5693473,   8.6640855,  -1.       ,  50.       ],
   [ 50.5693473,   8.6640855,   0.       , 111.       ],
   [ 50.5705819,   8.6597279,   2.       , 183.       ],
   [ 50.57067  ,   8.65694  ,   2.       , 257.       ],
   [ 50.57075  ,   8.65748  ,   1.       , 211.       ],
   [ 50.57075  ,   8.65748  ,   1.       , 292.       ],
   [ 50.5722461,   8.6598248,   2.       , 142.       ],
   [ 50.57254  ,   8.65895  ,   1.       , 116.       ],
   [ 50.57259  ,   8.6592   ,   2.       , 228.       ],
   [ 50.5731636,   8.667609 ,   1.       , 181.       ],
   [ 50.5737814,   8.6720067,   0.       , 173.       ],
   [ 50.5740356,   8.6718179,   1.       ,   5.       ],
   [ 50.5746321,   8.6831284,   3.       , 202.       ],
   [ 50.5747453,   8.6765588,   4.       , 119.       ],
   [ 50.5748992,   8.6611471,   2.       , 260.       ],
   [ 50.5748992,   8.6611471,   3.       , 102.       ],
   [ 50.575    ,   8.65985  ,   2.       , 267.       ],
   [ 50.5751   ,   8.66027  ,   2.       ,   7.       ],
   [ 50.5751   ,   8.66027  ,   2.       ,  56.       ],
   [ 50.57536  ,   8.67741  ,   1.       , 194.       ],
   [ 50.57536  ,   8.67741  ,   1.       , 282.       ],
   [ 50.5755255,   8.6884584,   0.       , 276.       ],
   [ 50.5755273,   8.674282 ,   3.       , 167.       ],
   [ 50.57553  ,   8.6826   ,   2.       , 273.       ],
   [ 50.5755973,   8.6847492,   0.       , 168.       ],
   [ 50.5756757,   8.6846139,   4.       , 255.       ],
   [ 50.57572  ,   8.65965  ,   0.       ,  66.       ],
   [ 50.57591  ,   8.68175  ,   1.       , 187.       ]])

将数组转换为数据框并重命名列:

df = pd.DataFrame(data=array_data) # convert back to dataframe

df.rename(columns={0: 'latitude', 1: 'longitude', 2:'floor', 3:'id'}, inplace=True) # rename columns

现在我们有了数据框。通过以下功能,我试图将人们分组:

首先我们需要找到一种方法,来获得与人们的距离:

def calculate_distance(lat1, lon1, lat2, lon2):
    """
    Calculate the shortest distance between two points given by the latitude and
    longitude.
    """
    earth_radius = 6373  # Approximate / in km.
    lat1 = radians(lat1)
    lon1 = radians(lon1)
    lat2 = radians(lat2)
    lon2 = radians(lon2)

    dlon = lon2 - lon1
    dlat = lat2 - lat1

    a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
    c = 2 * atan2(sqrt(a), sqrt(1 - a))
    return earth_radius * c  # in km.

这里是主要功能。如果他们的位置不同,我会尝试将他们分组:

def sort_people(all_persons, max_distance_parameter):

    '''
    People in the same group have different location!
    '''

    assert len(all_persons) % 9 == 0
    all_persons.set_index("id", drop=False, inplace=True)

    all_persons["host"] = np.nan
    all_persons["group"] = np.nan

    scattering_factor= 0.0001  # to seperate same floor numbers
    max_distance = max_distance_parameter
    group_number = 0
    group = []
    for _, candidate in all_persons.iterrows():
        if len(group) == 3:
            for person in group:
                all_persons.at[person["id"], "group"] = group_number
            group_number += 1
            group = []

        if len(group) == 0:
            group.append(candidate)
        else:
            for person in group:
                distance = calculate_distance(
                    candidate["latitude"],
                    candidate["longitude"],
                    person["latitude"],
                    person["longitude"],
                )
                distance = distance 

                if candidate['floor'] == -1:                 # consider the floor when calculating the distance 
                  distance = distance + scattering_factor + 0.001
                elif candidate['floor'] == 0:
                  distance = distance + scattering_factor + 0.002
                elif candidate['floor'] == 1:
                  distance = distance + scattering_factor + 0.003
                elif candidate['floor'] == 2:
                  distance = distance + scattering_factor + 0.004
                elif candidate['floor'] == 3:
                  distance = distance + scattering_factor + 0.005
                elif candidate['floor'] == 4:
                  distance = distance + scattering_factor + 0.006
                elif candidate['floor'] == 5:
                  distance = distance + scattering_factor + 0.007
                elif candidate['floor'] == 6:
                  distance = distance + scattering_factor + 0.008
                elif candidate['floor'] == 7:
                  distance = distance + scattering_factor + 0.009
                elif candidate['floor'] == 8:
                  distance = distance + scattering_factor + 0.010
                elif candidate['floor'] == 9:
                  distance = distance + scattering_factor + 0.011
                elif candidate['floor'] == 10:
                  distance = distance + scattering_factor + 0.012
                elif candidate['floor'] == 11:
                  distance = distance + scattering_factor + 0.013
                elif candidate['floor'] == 12:
                  distance = distance + scattering_factor + 0.014
                elif candidate['floor'] == 13:
                  distance = distance + scattering_factor + 0.015
                elif candidate['floor'] == 14:
                  distance = distance + scattering_factor + 0.016
                else:
                  distance = distance + scattering_factor + 0.017

                if 0 < distance <= max_distance:
                    group.append(candidate)
                    break

长话短说:这真的行不通。最后,我得到了一个数据框,我在相同的位置找到了被分配到同一组的人。你会怎么做?

【问题讨论】:

    标签: pandas dataframe sorting grouping


    【解决方案1】:

    使用您的解决方案,添加逻辑以查看具有相同坐标的人是否已经在组中。当您检查该组是否没有人时,请添加。但是如果组中有一个人,则为组中的每个人计算该人与候选人之间的距离。如果为 0,则中断(退出并且不要将该人添加到该组)。然后去下一组做同样的事情。

    顺便说一句。我不熟悉这种编程语言,所以我可能写了不好的语法,所以请使用上面的伪代码作为指导。干杯!

    if len(group) == 0:
                group.append(candidate)
            else:
                for person in group:
    
                    distance = calculate_distance(
                        candidate["latitude"],
                        candidate["longitude"],
                        person["latitude"],
                        person["longitude"],
                    )
                    distance = distance 
    
                    **if distance == 0 : break;** 
    
                    if candidate['floor'] == -1:                 # consider the floor when calculating the distance 
                      distance = distance + scattering_factor + 0.001
                    elif candidate['floor'] == 0:
                      distance = distance + scattering_factor + 0.002
                    elif candidate['floor'] == 1:
                      distance = distance + scattering_factor + 0.003
                    elif candidate['floor'] == 2:
                      distance = distance + scattering_factor + 0.004
                    elif candidate['floor'] == 3:
                      distance = distance + scattering_factor + 0.005
                    elif candidate['floor'] == 4:
                      distance = distance + scattering_factor + 0.006
                    elif candidate['floor'] == 5:
                      distance = distance + scattering_factor + 0.007
                    elif candidate['floor'] == 6:
                      distance = distance + scattering_factor + 0.008
                    elif candidate['floor'] == 7:
                      distance = distance + scattering_factor + 0.009
                    elif candidate['floor'] == 8:
                      distance = distance + scattering_factor + 0.010
                    elif candidate['floor'] == 9:
                      distance = distance + scattering_factor + 0.011
                    elif candidate['floor'] == 10:
                      distance = distance + scattering_factor + 0.012
                    elif candidate['floor'] == 11:
                      distance = distance + scattering_factor + 0.013
                    elif candidate['floor'] == 12:
                      distance = distance + scattering_factor + 0.014
                    elif candidate['floor'] == 13:
                      distance = distance + scattering_factor + 0.015
                    elif candidate['floor'] == 14:
                      distance = distance + scattering_factor + 0.016
                    else:
                      distance = distance + scattering_factor + 0.017
    
                    if 0 < distance <= max_distance:
                        group.append(candidate)
                        break
    

    【讨论】:

    • 语法不是 Python。也许我可以解决这个问题。你能告诉我,如何确保每个组包含 3 个人。不多不少。
    • 这很容易。在您开始将人员添加到组的部分中,计数到 3,在它变为 3 后,继续进行下一个循环迭代(代表下一个组)顺便说一句。我帮忙只是因为你是蜘蛛侠
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 2021-02-07
    • 2016-05-17
    • 2017-06-09
    相关资源
    最近更新 更多