(Python)Pandas - GroupBy()使用相似性函数

时间:2017-08-06 19:44:31

标签: python python-3.x pandas csv cluster-analysis

我正在使用Pandas在Python中使用csv文件。 我在思考如何实现以下目标时遇到了一些麻烦。 我需要实现的是使用相似性函数对条目进行分组。 例如,每个组X应包含所有条目,其中组中的每个对在特定的属性列值上最多为Y.

鉴于CSV的这个例子:

<pre>
name;sex;city;age
john;male;newyork;20
jack;male;newyork;21
mary;female;losangeles;45
maryanne;female;losangeles;48
eric;male;san francisco;29
jenny;female;boston2;30
mattia;na;BostonDynamics;50
</pre>

考虑到年龄栏,这个值差异最多为3,我会得到以下几组:

A = {john;male;newyork;20
   jack;male;newyork;21}
B={eric;male;san francisco;29
   jenny;female;boston2;30}
C={mary;female;losangeles;45
   maryanne;female;losangeles;48}
D={maryanne;female;losangeles;48
   mattia;na;BostonDynamics;50}

实际上这是我的解决办法,但我希望存在更多的pythonic。

import pandas as pandas
import numpy as numpy

def main():
    csv_path = "../resources/dataset_string.csv"
    csv_data_frame = pandas.read_csv(csv_path, delimiter=";")
    print("\nOriginal Values:")
    print(csv_data_frame)

    sorted_df = csv_data_frame.sort_values(by=["age", "name"], kind="mergesort")
    print("\nSorted Values by AGE & NAME:")
    print(sorted_df)

    min_age = int(numpy.min(sorted_df["age"]))
    print("\nMin_Age:", min_age)
    max_age = int(numpy.max(sorted_df["age"]))
    print("\nMax_Age:", max_age)

    threshold = 3
    bins = numpy.arange(min_age, max_age, threshold)
    print("Bins:", bins)
    ind = numpy.digitize(sorted_df["age"], bins)
    print(ind)

    print("\n\nClustering by hand:\n")
    current_min = min_age
    for cluster in range(min_age, max_age, threshold):
        next_min = current_min + threshold
        print("<Cluster({})>".format(cluster))
        print(sorted_df[(current_min <= sorted_df["age"]) & (sorted_df["age"] <= next_min)])
        print("</Cluster({})>\n".format(cluster + threshold))
        current_min = next_min


if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:1)

在一个属性上,这很简单:

  1. 排序
  2. 线性扫描数据,每当违反阈值时,开始一个新组。
  3. 虽然这不是最佳的,但它应该比现有的更好,成本更低。

    然而,在多变量情况下,找到最佳群体被认为是NP难的,因此找到最佳分组将需要在指数时间进行暴力搜索。因此,你需要通过AGNES(在O(n³)中)或CLINK(通常质量较差,但是O(n²))来近似这个。

    由于这相当昂贵,因此它不是数据框的简单操作符。