【问题标题】:Group by multiple columns based on distance between data points根据数据点之间的距离按多列分组
【发布时间】:2020-10-29 09:12:24
【问题描述】:

在下表中,1 行指的是 1 个属性。经纬度是指物业的GPS坐标,价格是物业的价格。 距离是一排和另一排之间的距离,以公里为单位。也就是说,0.1 是 100 米,0.05 是 50 米。

目标是对半径 100 米内的房产进行分组并获得平均价格。

   latitude longitude price distance0   distance1   distance2   distance3   distance4   distance5   distance6   distance7   distance8   distance9
0   55.6632 12.6288 2595000 0.000000    0.046580    0.046580    0.031053    0.031053    0.093159    0.046580    0.046580    0.046580    0.093159
1   55.6637 12.6291 2850000 0.046580    0.000000    0.000000    0.015527    0.015527    0.046580    0.000000    0.093159    0.093159    0.046580
2   55.6637 12.6291 2850000 0.046580    0.000000    0.000000    0.015527    0.015527    0.046580    0.000000    0.093159    0.093159    0.046580
3   55.6632 12.6290 3198000 0.031053    0.015527    0.015527    0.000000    0.000000    0.062106    0.015527    0.077633    0.077633    0.062106
4   55.6632 12.6290 2995000 0.031053    0.015527    0.015527    0.000000    0.000000    0.062106    0.015527    0.077633    0.077633    0.062106
5   55.6638 12.6294 2395000 0.093159    0.046580    0.046580    0.062106    0.062106    0.000000    0.046580    0.139739    0.139739    0.000000
6   55.6637 12.6291 2995000 0.046580    0.000000    0.000000    0.015527    0.015527    0.046580    0.000000    0.093159    0.093159    0.046580
7   55.6642 12.6285 4495000 0.046580    0.093159    0.093159    0.077633    0.077633    0.139739    0.093159    0.000000    0.000000    0.139739
8   55.6632 12.6285 3998000 0.046580    0.093159    0.093159    0.077633    0.077633    0.139739    0.093159    0.000000    0.000000    0.139739
9   55.6638 12.6294 3975000 0.093159    0.046580    0.046580    0.062106    0.062106    0.000000    0.046580    0.139739    0.139739    0.000000

生成的数据框将在末尾有一个新列,其中包含 100 米半径内房产的平均价格。

编辑: 想法是,如果我们以列“distance0”为例。遍历低于 0.1 的每个数据点,它应该获取这些数据点的价格,并在名为“avg_price_per_100m_radius”的新列中返回索引 0 中的平均值

【问题讨论】:

  • 你说的“半径100米以内”是什么意思?参考系的起源是什么? 100米从哪里来?此外,所有点的位置都使得所有距离列的值都小于 100 m(假设这是测量单位)。请考虑提供符合您标准的数据和一些不符合标准的数据。
  • 如果你仔细看,有些点超过了 100 米。 0.1 是 100 米。
  • 是的,你是对的。我第一次错过了。 0.1 is 100 meters, and 0.05 is 50 meters.
  • 没有问题,伙计:)

标签: python-3.x pandas group-by


【解决方案1】:

考虑到目标,要计算 100m 半径内的平均属性值,我不清楚在输出中包含 10 个额外列的目的。您可以执行以下操作,仅给出前三列:

from geopy.distance import geodesic

data = {"latitude": [55.6632, 55.6637, 55.6637], "longitude": [12.6288, 12.6291, 12.6294], "price":[2595000, 2850000, 2950000]}

df = pd.DataFrame(data)

df:

    latitude    longitude   price
0   55.6632     12.6288     2595000
1   55.6637     12.6291     2850000
2   55.6637     12.6294     2950000

构造一个自定义函数,并遍历每一行:

def get_average_prices(x):
    
    coords = (x["latitude"], x["longitude"])
    
    # Get distance to all other properties
    total_price = 0
    for _, row in df.iterrows():
        distance = geodesic(coords, (row["latitude"], row["longitude"])).meters
        if distance <= 100:
            total_price += row["price"]
            
    # Dont count itself (the current row)
    total_price -= x["price"] 
    x['avg_price'] = total_price/(len(df)-1)
    
    return x

df.apply(lambda x: get_average_prices(x), axis=1)

输出:

    latitude    longitude   price       avg_price
0   55.6632     12.6288     2595000.0   2900000.0
1   55.6637     12.6291     2850000.0   2772500.0
2   55.6637     12.6294     2950000.0   2722500.0

平均价格包括房产本身,尽管这可以很容易地在代码中进行调整。此方法速度较慢,因此如果您的 DataFrame 很大,您可能需要开发一种更快的矢量化方法。

【讨论】:

  • 感谢您的努力,但对于我的情况来说绝对太慢了。
【解决方案2】:

解决方案

你可以试试这个。

dist_cols = [f'distance{i}' for i in range(df.index.size)]
df['avg_price'] = (
    (df.loc[:, dist_cols] < 0.1).to_numpy().astype(int) * 
    (df.price.to_numpy().reshape(-1, 1))
).mean(axis=0)

输出

仔细观察

要了解它的工作原理,请尝试运行以下代码块。

pd.DataFrame((df.loc[:, dist_cols] < 0.1).to_numpy().astype(int) * (df.price.to_numpy().reshape(-1, 1)), columns=dist_cols)

虚拟数据

我更喜欢添加 dummy-data 部分以实现答案的可重复性。

import numpy as np
import pandas as pd

from io import StringIO

import warnings
warnings.filterwarnings("ignore")

## Dataframe as string
s = """
   latitude longitude price distance0   distance1   distance2   distance3   distance4   distance5   distance6   distance7   distance8   distance9
0   55.6632 12.6288 2595000 0.000000    0.046580    0.046580    0.031053    0.031053    0.093159    0.046580    0.046580    0.046580    0.093159
1   55.6637 12.6291 2850000 0.046580    0.000000    0.000000    0.015527    0.015527    0.046580    0.000000    0.093159    0.093159    0.046580
2   55.6637 12.6291 2850000 0.046580    0.000000    0.000000    0.015527    0.015527    0.046580    0.000000    0.093159    0.093159    0.046580
3   55.6632 12.6290 3198000 0.031053    0.015527    0.015527    0.000000    0.000000    0.062106    0.015527    0.077633    0.077633    0.062106
4   55.6632 12.6290 2995000 0.031053    0.015527    0.015527    0.000000    0.000000    0.062106    0.015527    0.077633    0.077633    0.062106
5   55.6638 12.6294 2395000 0.093159    0.046580    0.046580    0.062106    0.062106    0.000000    0.046580    0.139739    0.139739    0.000000
6   55.6637 12.6291 2995000 0.046580    0.000000    0.000000    0.015527    0.015527    0.046580    0.000000    0.093159    0.093159    0.046580
7   55.6642 12.6285 4495000 0.046580    0.093159    0.093159    0.077633    0.077633    0.139739    0.093159    0.000000    0.000000    0.139739
8   55.6632 12.6285 3998000 0.046580    0.093159    0.093159    0.077633    0.077633    0.139739    0.093159    0.000000    0.000000    0.139739
9   55.6638 12.6294 3975000 0.093159    0.046580    0.046580    0.062106    0.062106    0.000000    0.046580    0.139739    0.139739    0.000000
"""

## Read dataframe
df = pd.read_csv(StringIO(s), sep='\s*',engine='python', delimiter=None)

【讨论】:

  • @doomdaam 请看看这个,如果您有任何问题,请告诉我。我希望这就是你要找的。​​span>
  • 输出似乎是错误的。我测试了你在 Excel 表中得到的平均值,结果没有加起来。
  • 好的。因此,让我澄清一下逻辑:您希望将每列 (distance0 ... distance9) 的平均值作为avg_price 列,其中为distance &lt; 0.1 选择列数据,并且在有效的情况下,我们只为这些行获取价格。对吗?
猜你喜欢
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 2019-02-24
  • 2014-05-22
  • 1970-01-01
  • 2019-02-20
  • 2013-11-02
相关资源
最近更新 更多