假设我有一个函数来比较一个rabrame中的行:

def comp(lhs: pandas.Series, rhs: pandas.Series) -> bool:
  if lhs.id == rhs.id:
    return True

  if abs(lhs.val1 - rhs.val1) < 1e-8:
    if abs(lhs.val2 - rhs.val2) < 1e-8:
      return True

  return False

现在,我有一个包含idval1val2列的子帧,我想生成组ID,以便任何两行的comp计算为true都有组号.我该如何处理Pandas ?我一直在想办法让groupby实现这一点,但想不出办法.

MRE:

example_input = pandas.DataFrame({
    'id' : [0, 1, 2, 2, 3],
    'value1' : [1.1, 1.2, 1.3, 1.4, 1.1],
    'value2' : [2.1, 2.2, 2.3, 2.4, 2.1]
})

example_output = example_input.copy()
example_output.index = [0, 1, 2, 2, 0]
example_output.index.name = 'groups'

推荐答案

您希望对属于同一组或距离较近的行进行聚类.为此,用scipy.spatial.distance.pdist计算距离以识别接近点,并创建一个用networkx来识别连接组件的图:

import networkx as nx
import pandas as pd
from scipy.spatial.distance import pdist
from itertools import combinations

# example input
df = pandas.DataFrame({
    'id' : [0, 1, 2, 2, 3],
    'value1' : [1.1, 1.2, 1.3, 1.4, 1.1],
    'value2' : [2.1, 2.2, 2.3, 2.4, 2.1]
})

thresh = 1e-8
cols = ['value1', 'value2']

# create graph based on already connected ids
G = nx.compose_all(map(nx.path_graph, df.index.groupby(df['id']).values()))

# add pairs of values with distance below threshold as edges
G.add_edges_from(pd.Series(combinations(df.index, 2))
                 [pdist(df[cols])<thresh]
                )

# form groups based on the connected components
groups = {n: i for i, c in enumerate(nx.connected_components(G))
          for n in c}
# {0: 0, 4: 0, 1: 1, 2: 2, 3: 2}

# update index based on above dictionary
df.index = df.index.map(groups)

输出:

   id  value1  value2
0   0     1.1     2.1
1   1     1.2     2.2
2   2     1.3     2.3
2   2     1.4     2.4
0   3     1.1     2.1

图(仅基于ID;数字是原始索引):

enter image description here

曲线图(考虑距离后):

enter image description here

Python相关问答推荐

为什么tkinter框架没有被隐藏?

对于一个给定的数字,找出一个整数的最小和最大可能的和

有症状地 destruct 了Python中的regex?

删除所有列值,但判断是否存在任何二元组

如何使用pytest来查看Python中是否存在class attribution属性?

使用Python从rotowire中抓取MLB每日阵容

查看pandas字符列是否在字符串列中

递归函数修饰器

Python—在嵌套列表中添加相同索引的元素,然后计算平均值

Pandas在rame中在组内洗牌行,保持相对组的顺序不变,

如何使用大量常量优化代码?

为什么后跟inplace方法的`.rename(Columns={';b';:';b';},Copy=False)`没有更新原始数据帧?

使用美汤对维基百科表格进行网络刮擦未返回任何内容

迭代工具组合不会输出大于3的序列

Pandas ,快速从词典栏中提取信息到新栏

如何在不遇到IndexError的情况下将基数10的整数转换为基数80?

将鼠标悬停在海运`pairplot`的批注/高亮显示上

如何在networkx图中提取和绘制直接邻居(以及邻居的邻居)?

如何使用count()获取特定日期之间的项目

运行从Airflow包导入的python文件,需要airflow实例?