Gavin_Stargazer 2021-10-08 16:01 采纳率: 62.5%
浏览 182
已结题

【python】给定数组,按相邻元素差额分组


# 一、示例:原始数据
num_list = [393, 393, 394, 394, 394, 423, 424, 424, 425, 425, 454, 454, 454, 454, 456]


# 二、示例:分组结果
part_1 = [393, 393, 394, 394, 394]
part_2 = [423, 424, 424, 425, 425]
part_3 = [454, 454, 454, 454, 456]


# 三、数组说明
# 1、确定的事项
#   1-1 给定的列表,已按由小到大排列好;
#   1-2【同组相邻数字的差额】一定明显大于【两组间相领数字的差额】。以上述案例为例:【同组相邻数字的差额】小于3,【两组间相领数字的差额】远大于3;
# 2、不确定事项
#   2-1 列表元素总个数不确定;
#   2-2 可拆分成几组不确定;可能拆分成4-5组
#   2-3 每组元素的个数不确定;可能是案例中的5个,也可能是8-10个
#   2-4 【同组相邻数字的差额】不一定小于3,比如可能出现[1,5,7,21,25,29]这种场景


# 请问如何使用python实现,或提供拆分思路也可以,谢谢
  • 写回答

5条回答 默认 最新

  • 广大菜鸟 2021-10-08 18:11
    关注

    我想到可以用导数的方法把差值拉大,然后可以划分
    2种方法如下,一阶和二阶导数(这也就要求至少有2个以上的数)
    想法:

    """
    # 一、示例:原始数据
    num_list = [393, 393, 394, 394, 394, 423, 424, 424, 425, 425, 454, 454, 454, 454, 456]
    
    # 二、示例:分组结果
    part_1 = [393, 393, 394, 394, 394]
    part_2 = [423, 424, 424, 425, 425]
    part_3 = [454, 454, 454, 454, 456]
    
    依次顺序:原来式子:,一阶导数,二阶导数,正则化二阶导数再提取变化最大特征的二阶导数,还原一阶导数
    [393, 393, 394, 394, 394, 423, 424, 424, 425, 425, 454, 454, 454, 454, 456]
        [0, -1,   0,   0,   -29,  -1,  0,  -1,  0,  -29,   0,  0,    0,  -2]    
          [1,  -1,  0,  29,   -28,  -1,  1,  -1,  29,  -29, 0, 0, 2]
          [0,  0,   0,   1,    1,    0,   0,   0,   1,  1,  0,  0, 0]
        [0,  0,   0,   0,   1,     0,    0,    0,  0,   1,  0,  0, 0,  0]  
     [0, 0,   0,   0,   0,    1,     0,    0,   0,  0,   1,  0,  0, 0, 0]  这个可以代表分界线  
    """
    
    

    一阶导数

    
    num_list = [0, 394, 454, 456]  # 3个起步
    # 前向递推法
    firstD = [num_list[i] - num_list[i + 1] for i in range(len(num_list) - 1)]  # 一阶导数
    tmpFirstD = [abs(item) for item in firstD]
    
    minValue = np.min(tmpFirstD)
    maxValue = np.max(tmpFirstD)
    newFirstD = [0] + [int(round((item - minValue) / (maxValue - minValue))) for item in tmpFirstD] 
    newFirstDLen = len(newFirstD)
    # 一阶 =》 原式
    res = []
    for i in range(newFirstDLen):
        if i == 0:
            res.append([num_list[i]])
        elif newFirstD[i] == 0:
            res[len(res) - 1].append(num_list[i])
        elif newFirstD[i] == 1:
            res.append([num_list[i]])
    print(res)
    

    二阶求导

    num_list = [393, 393, 394, 394, 394, 423, 424, 424, 425, 425, 454, 454, 454, 454, 456]  # 4个起步
    firstD = [num_list[i] - num_list[i + 1] for i in range(len(num_list) - 1)]  # 一阶导数
    tmpFirstD = [abs(item) for item in firstD]
    
    secondD = [firstD[i] - firstD[i + 1] for i in range(len(firstD) - 1)]  # 二阶导数
    tmpSecondD = [abs(item) for item in secondD]
    
    
    minValue = np.min(tmpSecondD)
    maxValue = np.max(tmpSecondD)
    tmpSecondD = [int(round((item - minValue) / (maxValue - minValue))) for item in tmpSecondD]
    tmpSecondDLen = len(tmpSecondD)
    
    # 二阶 =》 一阶
    i = 0
    while i < tmpSecondDLen:
        if tmpSecondD[i] == 1 and i < tmpSecondDLen - 1 and tmpSecondD[i + 1] == 1:
            tmpSecondD[i] = 0
            i += 2
        else:
            i += 1
    
    newFirstD = [0] + tmpSecondD + [0]  
    newFirstDLen = len(newFirstD)
    
    # 一阶 =》 原式
    res = []
    for i in range(newFirstDLen):
        if i == 0:
            res.append([num_list[i]])
        elif newFirstD[i] == 0:
            res[len(res) - 1].append(num_list[i])
        elif newFirstD[i] == 1:
            res.append([num_list[i]])
    print(res)
    

    img

    其他案例:
    如果个数不多就用1阶

    img

    img

    img

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(4条)

报告相同问题?

问题事件

  • 系统已结题 10月17日
  • 已采纳回答 10月9日
  • 修改了问题 10月9日
  • 创建了问题 10月8日

悬赏问题

  • ¥15 关于#vscode#的问题:ESP32开发板对接MQTT实现小灯泡的开关
  • ¥15 TMC2209串口模式下读取不到寄存器的值串口助手蓝色字体是发过去的消息,绿色字体是收到的消息,第二行发送读取寄存器的指令但是没有读取到寄存器的值串口助手如下图:接线如下图,如何解决?
  • ¥15 高通安卓11提取完整线刷包软件,或者优博讯dt50顺丰刷机包
  • ¥20 C,有个译码器,换了信道就跑不出原来数据
  • ¥15 MIMIC数据库安装问题
  • ¥60 基于JTag协议开发Fpga下载器上位机,哪位大🐂有偿指导?
  • ¥20 全书网Java爬取数据
  • ¥15 怎么获取红包封面的原始链接,并且获取红包封面序列号
  • ¥100 微信小程序跑脚本授权的问题
  • ¥100 房产抖音小程序苹果搜不到安卓可以付费悬赏