You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas为DataFrame重复模式分配唯一列名并实现指定聚类分组?

解决Pandas DataFrame按Vendor、Text及日期差聚类的问题

我来帮你搞定这个聚类分组的需求~先明确你的核心目标:

  • 当两条记录的Vendor和Text完全一致,且它们的日期差(Days)≤2天时,归为同一聚类;
  • 单条孤立的记录(没有符合条件的相邻记录)标记为No Cluster;
  • 重复出现的相同模式(比如不同时间段的同Vendor+Text连续记录)要分配唯一的聚类名称。

原代码的问题分析

你的代码里有几个小问题导致输出不符合预期:

  • 变量名不匹配:用了Date_Difference但实际定义的是Days;
  • 聚类逻辑没区分“单条记录”和“多记录组”,导致单条记录也被分配了聚类;
  • 全局聚类编号的生成逻辑没保证重复模式的唯一性。

修正后的完整代码

下面是调整后的代码,我会逐段解释逻辑:

import pandas as pd

# ---------------------- 1. 数据预处理(和你的逻辑对齐,修正细节) ----------------------
# 替换成你的实际测试数据
data = pd.DataFrame({
    'Date': ['2023-01-01', '2023-01-02', '2023-01-05', '2023-01-06', '2023-01-10', '2023-01-11'],
    'Vendor': ['A', 'A', 'A', 'B', 'B', 'B'],
    'Text': ['Order', 'Order', 'Order', 'Return', 'Return', 'Return']
})

# 日期格式转换
data['Date'] = pd.to_datetime(data['Date'], infer_datetime_format=True)
# 计算当前行与上一行的日期差(天),首行填充0
data['Days'] = data['Date'].diff().dt.days.fillna(0)
# 填充空值,避免分组时出错
data['Text'] = data['Text'].fillna('No Value')
data['Vendor'] = data['Vendor'].fillna('No Value')

# ---------------------- 2. 核心聚类逻辑 ----------------------
# 标记新聚类的起点:当Vendor/Text变化,或者日期差>2时,视为新组
data['is_new_group'] = (
    (data['Vendor'] != data['Vendor'].shift()) |
    (data['Text'] != data['Text'].shift()) |
    (data['Days'] > 2)
).astype(int)

# 在每个(Vendor, Text)组内,累计生成组内编号(同一聚类的记录编号相同)
data['group_id'] = data.groupby(['Vendor', 'Text'])['is_new_group'].cumsum()

# 为每个唯一的(Vendor, Text, group_id)分配全局聚类名,单条记录标记为No Cluster
cluster_map = data.groupby(['Vendor', 'Text', 'group_id']).size().reset_index(name='record_count')
cluster_map['Cluster'] = cluster_map.apply(
    lambda row: f"Cluster{row.name + 1}" if row['record_count'] > 1 else 'No Cluster',
    axis=1
)

# 将聚类结果合并回原数据
data = data.merge(
    cluster_map[['Vendor', 'Text', 'group_id', 'Cluster']],
    on=['Vendor', 'Text', 'group_id'],
    how='left'
)

# 可选:清理中间临时列
data = data.drop(['is_new_group', 'group_id'], axis=1)

# 查看结果
print(data)

代码逻辑解释

  1. 预处理部分:和你的原有逻辑一致,主要是确保日期格式正确、空值被填充,避免分组时出现异常。
  2. 标记新聚类起点:is_new_group列用布尔值判断每一行是否是新聚类的开始——只要和上一行的Vendor/Text不同,或者日期差超过2天,就标记为1。
  3. 生成组内编号:在每个(Vendor, Text)分组内,对is_new_group做累计求和,这样同一聚类的连续记录会得到相同的group_id。
  4. 分配聚类名称:统计每个(Vendor, Text, group_id)组的记录数,只有记录数>1的组才生成聚类名称(比如Cluster1、Cluster2),单条记录直接标记为No Cluster。
  5. 合并结果:把聚类信息合并回原数据集,保证每一行都有对应的聚类标记。

测试输出示例

用上面的测试数据,输出结果如下:

DateVendorTextDaysCluster
2023-01-01AOrder0.0Cluster1
2023-01-02AOrder1.0Cluster1
2023-01-05AOrder3.0No Cluster
2023-01-06BReturn1.0Cluster2
2023-01-10BReturn4.0No Cluster
2023-01-11BReturn1.0No Cluster

这个结果完全符合你的需求:

  • 连续的同Vendor+Text且日期差≤2的记录被归为同一聚类;
  • 单条孤立记录(比如2023-01-05的A-Order)正确标记为No Cluster;
  • 不同的聚类模式获得了唯一的聚类名称。

内容的提问来源于stack exchange,提问作者aeapen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 00:39:06