yolo利用txt可视化碰到的问题

博客内容涉及两个问题:1. 由于存在0KB的txt文件导致可视化程序出现`IndexError: too many indices for array`错误,解决方案是删除这些无效文件及其对应图片。2. 可视化图片上缺少标签框,原因是txt文件中标签和坐标输出顺序不正确,修正输出顺序即可解决。

问题一:

IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed

报错原因:

可视化用的txt文件夹里面有的txt文件是0kb,无法可视化,程序报错。

参考地址:

遇到IndexError: too many indices for array: array is 1-dimensional, but 2 were i..问题_dear_queen的博客-优快云博客icon-default.png?t=M3K6https://blog.youkuaiyun.com/dear_queen/article/details/116230861?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165061835316782184641455%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165061835316782184641455&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-116230861.142^v9^pc_search_result_cache,157^v4^control&utm_term=IndexError%3A+too+many+indices+for+array%3A+array+is+1-dimensional%2C+but+2+were+indexed&spm=1018.2226.3001.4187

解决办法:

将0kb的txt文件删除,同时将删除的txt文件名相对应的照片也删除就可以了。

问题二:

照片根据txt可视化完成以后发现可视化的照片上面无任何标签框。

在csdn找了好久没没有找到相关的问题,就对程序进行了单步调试,发现我的txt文件里面前四位是pred_boxes,第五位是pred_labels,但是在我读取的时候是读取的第一位是标签,所以在检测生成txt的时候改变一下输出的顺序就好了。先输出pred_labels,后输出pred_boxs.

print(
      int(pred_labels[i]),
      *[int(p) for p in pred_boxes[i]],
      float(pred_scores[i]),
      file=f)

txt输出改成如上图所示就好了。

<think>我们正在处理一个关于Java数组排序和排名的问题。用户希望了解如何对一维数组进行排名排序并打印。 排名排序(Rank sort)意味着我们不仅要排序,还要给每个元素分配一个排名(rank)。排名通常表示元素在排序后的位置(例如,最小的元素是第1名,次小的第2名,等等)。 步骤: 1. 复制原始数组,因为我们不想改变原始数组的顺序。 2. 对复制的数组进行排序。 3. 创建一个排名数组(或映射),以便我们可以知道原始数组中每个元素的排名。 4. 打印排序后的数组和排名。 注意:排名可能有不同的处理方式,例如,相同元素可能有相同的排名(并列)或者跳过后续名次(如:1,2,2,4)。这里我们采用常见的并列排名,即相同元素有相同排名,然后下一个元素跳过并列占用的名次(比如两个并列第一,则下一个是第三名)?但实际上,常见的做法是:如果并列,则它们都获得相同的排名(例如并列第一),然后下一个排名接着当前的位置加上并列的数量。但是,另一种常见的方法是密集排名(dense rank)和非密集排名(竞争排名)。这里我们按照常见的“竞争排名”(即并列排名后跳过后续名次)?但用户没有特别说明,我们可以采用标准做法:相同数值具有相同排名,并跳过后续名次(如:1, 2, 2, 4)或者也可以采用连续排名(1,2,2,3)?这取决于需求。 然而,用户没有特别说明,我们可以采用以下两种方式之一: 方法A:竞争排名(rank by competition):例如,[3, 1, 4, 1, 5] -> 排序后[1,1,3,4,5],排名:1,1,3,4,5(两个1都是第一名,然后3是第三名,因为第二名被跳过了)。 方法B:密集排名(dense rank):相同元素排名相同,但后续排名连续(即不跳过名次):[1,1,2,3,4] -> 排名:1,1,2,3,4。 但通常在排序中,当我们说排名时,竞争排名(方法A)更常见。但是,我们也可以提供两种选择。 然而,问题要求的是“排名排序”,所以我们不仅要排序,还要分配排名。然后打印。 在Java中,我们可以这样做: 1. 复制数组并排序。 2. 创建一个映射(Map)来记录每个元素的排名。但是注意,相同元素可能多次出现,所以我们需要考虑重复元素。 我们可以遍历排序后的数组,然后给每个位置分配一个排名。但是因为可能有重复元素,所以不能简单地按位置给排名(因为位置0的排名是1,但是如果有重复,那么重复的元素都应该有相同的排名)。 步骤: 方案1(竞争排名): - 对复制数组排序(升序)。 - 初始化一个排名变量(rank=1)和一个用于存储排名的数组(与原数组等长)。 - 然后,我们遍历排序后的数组,对于排序数组中的第i个元素: 如果i>0且当前元素不等于前一个元素,则排名更新为当前的位置i+1(或者更准确地,应该等于当前已经排名的元素个数+1?)但实际上,竞争排名的做法是:排名等于当前位置(从1开始)减去前面重复元素的个数?这样并不直接。 实际上,我们可以这样做: - 创建一个Map<Integer, Integer>,存储每个元素的排名(注意:相同元素应该具有相同的排名)。 - 但是,如果我们遍历排序后的数组,我们可以将每个元素第一次出现的位置(索引)作为排名?不对。 更直接的方法: - 排序数组:sortedArr - 然后创建一个排名数组:ranks,大小与sortedArr相同。 - 设置ranks[0] = 1- 从i=1开始遍历: if (sortedArr[i] == sortedArr[i-1]) { ranks[i] = ranks[i-1]; // 与前一个排名相同 } else { ranks[i] = i+1; // 因为索引从0开始,所以排名是i+1?但是这样会出现:如果前两个相同,第一个排名为1,第二个也是1,第三个不同,那么第三个排名为3(跳过2),这正是竞争排名。 } - 但是,这样分配的排名是基于排序后数组的,我们还需要知道原始数组中每个元素的排名。 因此,我们需要一个结构来记录每个元素的排名。但是注意,同一个元素可能有多个,而且它们在原始数组中的位置不同。所以,我们还需要将排名映射回原始数组。 步骤: 1. 复制原始数组:double[] arrCopy = Arrays.copyOf(originalArr, originalArr.length); 2. 排序arrCopy。 3. 创建一个Map(元素->排名),但由于元素重复,不能直接映射。所以我们可以创建一个数组,用于存储原始数组每个元素的排名。同时,我们需要知道每个元素在排序数组中的排名(竞争排名)。 4. 另一种思路:我们创建一个排名数组(rankArray),其大小与原始数组相同。然后,对于原始数组中的每个元素,我们查找它在排序后数组中的位置(第一次出现的位置),然后根据该位置计算排名(竞争排名:排名=位置索引+1)。但是,如果有重复元素,那么排序后数组中有多个相同元素,我们取第一次出现的位置(即最小的排名)作为该元素的排名?这样原始数组中所有相同的元素都会得到相同的排名(即它们第一次出现时的排名)。这符合我们的要求。 但是,如何获取排名?我们可以: - 创建一个Map,用于存储每个元素对应的排名(竞争排名)。在排序数组sortedArr中,我们遍历,并记录每个元素第一次出现时的排名(即前面所述方法:如果当前元素与前一个相同,则排名不变;否则,排名为当前索引+1)。然后,我们将每个元素和它对应的排名存入Map。注意,同一个元素只需要记录一次(第一次出现时)?但是后面相同的元素也会被覆盖为同一个排名?不对,因为我们在遍历排序数组时,同一个元素第一次出现时我们设置排名,然后后面再遇到相同的元素,我们不会更新排名(因为相同元素在排序后相邻,所以第一次出现时已经确定了排名,而且后续相同元素我们不会重新赋值)。但是,这样我们构建的Map中每个元素只有一个排名值,这样当我们查找原始数组中某个元素的排名时,就可以得到这个值。 但是,这种方法有一个问题:如果同一个元素在排序数组中出现多次,那么它们实际上应该共享相同的排名(竞争排名)。所以,我们只需要记录每个元素对应的排名(第一次出现时确定的排名)。这样,原始数组中的每个元素,我们都可以通过Map得到它的排名。 因此,具体步骤: 1. 复制原始数组并排序(升序)。 2. 创建一个Map:Map<Integer, Integer> map = new HashMap<>(); 3. 遍历排序后的数组,对于索引i: if (!map.containsKey(sortedArr[i])) { // 如果这个元素还没有被记录过 map.put(sortedArr[i], i+1); // 排名为i+1(因为i从0开始,所以+1) } 注意:这样,重复元素就不会再次放入map(因为它们已经存在)。所以,每个元素的排名就是它在排序后数组中第一次出现的位置(索引+1)。但是,这个排名值就是竞争排名(因为重复元素不会再次更新,所以它们的排名都是第一次出现时的排名,也就是最小的排名)。而且,排序数组是升序,所以第一个最小元素排名1,第二个如果重复则还是1,如果不重复就是2,以此类推。但是,这样做的排名值实际上是该元素在排序数组中第一次出现的索引+1,这个值正好是竞争排名(跳过重复元素后的排名)。 例如:[3, 1, 4, 1, 5] -> 排序后:[1,1,3,4,5] 索引0: 元素1,放入map:1->1 索引1: 元素1,已存在,跳过 索引2: 元素3,放入map:3->3(因为索引2,所以2+1=3) 索引3: 元素4,放入map:4->4 索引4: 元素5,放入map:5->5 所以,原始数组中的两个1都会得到排名1,3得到3,4得到4,5得到5。这就是竞争排名(跳过了第2名)。 4. 然后,我们遍历原始数组,对于每个元素,从map中取出对应的排名,并打印。 但是,用户要求的是“排名排序并打印”,打印什么?排序后的数组?还是原始数组的排名?或者两者都打印?根据问题,可能是打印原始数组的每个元素对应的排名,以及排序后的数组。 因此,我们可以: - 打印原始数组。 - 打印每个元素的排名(按原始数组的顺序)。 - 也可以打印排序后的数组。 但是,问题描述中说“对一维数组进行排名排序并打印”,所以可能是打印排序后的数组,同时每个元素对应一个排名?或者打印排名数组?我们可以这样理解: 输入数组: [3, 1, 4, 1, 5] 我们希望得到排名数组: [3, 1, 4, 1, 5] 的排名是什么? -> 排名数组应该是 [3, 1, 4, 2, 5]?不对,因为有两个1,所以应该是: 原始数组:3 -> 排名为3(因为它在排序后数组中是第三名?注意:排名是针对元素值,而不是位置) 实际上,原始数组中的第一个3,它的值是3,在排序后数组中是第三小的,所以排名为3。 第一个1,排名为1;第二个1,排名也为1;4排名为4;5排名为5。 但是我们上面使用map的方式,原始数组中的每个元素根据其值得到排名。所以: 原始数组: [3, 1, 4, 1, 5] 排名数组: [3, 1, 4, 1, 5] 对应的排名:第一个3 -> 3,第一个1 -> 1,4 -> 4,第二个1 -> 1,5->5。 所以排名数组为:[3, 1, 4, 1, 5] 然后,如果我们想要打印排序后的数组,则排序后数组为:[1,1,3,4,5],并且排名数组(按排序后数组的顺序)为:[1,1,3,4,5](但这里排名数组就是排序后数组的排名?实际上排序后数组的排名我们已经知道了:第一个1排名1,第二个1排名1,3排名3,4排名4,5排名5),所以打印排序后数组时,也可以同时打印排名。 但是,用户要求的是“排名排序并打印”,所以我们可以选择输出两种: 1. 原始数组及其每个元素的排名(即排名数组)。 2. 排序后的数组(每个元素后面跟着排名)?但排序后数组的排名我们已经知道了(在构建map时已经确定了每个值的排名),所以也可以打印。 根据问题,用户可能只需要打印原始数组的排名,或者排序后的数组以及排名。但是,问题没有明确,所以我们两种都提供。 另外,我们还可以打印排序后的数组(带排名)?但是排序后的数组中,相同元素的排名相同,所以打印时每个元素对应的排名就是我们在map中存储的。 因此,我们可以这样设计输出: 原始数组: [3, 1, 4, 1, 5] 排名数组: [3, 1, 4, 1, 5] -> 这里排名数组的值就是每个元素的排名 排序并带排名: 1 (排名1) 1 (排名1) 3 (排名3) 4 (排名4) 5 (排名5) 但是,排名数组和原始数组的顺序一致,而排序并带排名则是按照排序后的顺序。 现在,我们可以写代码了。 注意:如果我们需要密集排名(dense rank)怎么办? 密集排名:相同元素排名相同,但后续排名连续(不跳过名次)。例如:[1,1,3,4,5] -> 排名为[1,1,2,3,4] 我们可以修改构建map的方式: 初始化一个变量currentRank=1 遍历排序后的数组(升序): 如果i>0且当前元素不等于前一个元素,则currentRank++(因为遇到新元素,排名加1) 然后,如果当前元素不在map中,就将currentRank作为该元素的排名放入map。 这样,重复元素不会增加currentRank,所以同一个元素放入map的排名相同,而且连续。 但是,用户没有指定,我们就按竞争排名(竞争排名更常见)实现。 因此,我们提供两种方法:竞争排名和密集排名,由用户选择?但问题没有指定,所以我们可以先实现竞争排名,然后如果需要,再提供密集排名。 现在,我们写一个Java程序,使用竞争排名。 代码步骤: 1. 读取原始数组(假设为int数组)。 2. 复制数组并排序。 3. 创建一个HashMap用于存储元素到排名的映射。 4. 遍历排序后的数组: for (int i = 0; i < sortedArray.length; i++) { // 如果这个元素还没有在map中,我们就放入,键为元素值,值为排名(i+1) if (!map.containsKey(sortedArray[i])) { map.put(sortedArray[i], i+1); } } 5. 创建原始数组的排名数组:创建一个数组ranks,大小与原始数组相同,然后遍历原始数组,对于每个元素,从map中取出排名,放入ranks数组的对应位置。 6. 打印原始数组。 7. 打印排名数组。 8. 打印排序后的数组(带排名)?可选。 但是,注意:如果数组中包含负数或0?没问题。 示例代码: 另外,如果数组很大,使用HashMap可能比每次在排序数组中进行二分查找更快?但这里我们使用HashMap是O(1)的查找,所以效率高。 下面我们写代码: 注意:由于Java中数组排序是升序,所以排名1表示最小值。 如果用户需要降序排列,那么排名1表示最大值?但问题没有说明,我们按升序处理。 代码实现: </think>在Java中,对一维数组进行排名排序(Rank Sort)并打印的实现如下。排名排序会给数组中的每个元素分配一个排名(从1开始),相同值的元素可能获得相同或不同的排名,具体取决于采用的排名策略。这里演示两种常见策略:**竞争排名(Competition Rank)** 和 **密集排名(Dense Rank)**。 ### 1. 竞争排名(Competition Rank) 相同值元素排名相同,但会跳过后续名次(如:1, 2, 2, 4)。实现代码: ```java import java.util.*; public class RankSort { public static void main(String[] args) { int[] array = {5, 2, 3, 2, 8}; // 示例数组 // 步骤1: 获取排序后的数组副本 int[] sortedArray = array.clone(); Arrays.sort(sortedArray); // 步骤2: 创建竞争排名映射表(值 -> 排名) Map<Integer, Integer> rankMap = new HashMap<>(); for (int i = 0; i < sortedArray.length; i++) { // 仅当首次出现该值时记录排名 (i+1) rankMap.putIfAbsent(sortedArray[i], i + 1); } // 步骤3: 生成原始数组的排名数组 int[] ranks = new int[array.length]; for (int i = 0; i < array.length; i++) { ranks[i] = rankMap.get(array[i]); } // 打印结果 System.out.println("原始数组: " + Arrays.toString(array)); System.out.println("竞争排名: " + Arrays.toString(ranks)); } } ``` **输出**: ``` 原始数组: [5, 2, 3, 2, 8] 竞争排名: [4, 1, 3, 1, 5] // 解释:21, 21, 3→3, 5→4, 8→5(跳过第2名) ``` ### 2. 密集排名(Dense Rank) 相同值元素排名相同,且后续名次不跳过(如:1, 2, 2, 3)。实现代码: ```java import java.util.*; public class RankSort { public static void main(String[] args) { int[] array = {5, 2, 3, 2, 8}; // 示例数组 // 步骤1: 获取排序后的数组副本 int[] sortedArray = array.clone(); Arrays.sort(sortedArray); // 步骤2: 创建密集排名映射表(值 -> 排名) Map<Integer, Integer> rankMap = new HashMap<>(); int currentRank = 1; for (int i = 0; i < sortedArray.length; i++) { // 遇到新值时更新排名 if (i > 0 && sortedArray[i] != sortedArray[i - 1]) { currentRank++; } rankMap.put(sortedArray[i], currentRank); } // 步骤3: 生成原始数组的排名数组 int[] ranks = new int[array.length]; for (int i = 0; i < array.length; i++) { ranks[i] = rankMap.get(array[i]); } // 打印结果 System.out.println("原始数组: " + Arrays.toString(array)); System.out.println("密集排名: " + Arrays.toString(ranks)); } } ``` **输出**: ``` 原始数组: [5, 2, 3, 2, 8] 密集排名: [3, 1, 2, 1, 4] // 解释:21, 21, 3→2, 5→3, 8→4 ``` ### 关键说明: 1. **排名策略选择**: - 竞争排名:适用于需要严格区分名次的场景(如体育比赛)。 - 密集排名:适用于需要连续排名的场景(如成绩分级)。 2. **时间复杂度**:$O(n \log n)$ (由排序操作主导)。 3. **空间复杂度**:$O(n)$ (存储副本和映射表)。 ### 扩展应用 两种方法均可用于: - 学生成绩排名 - 算法竞赛得分统计 - 数据分析中的分位数计算
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值