当前位置: 首页 > news >正文

二道题:分组顺序向下填充 和 标注数据整理

分组顺序向下填充

需求

之前群友分享这样一道Pandas题:

应用pandas模块,导入“python_test.xlsx”的excel中的表格数据(2个sheet)

要求:
将sheet1表数据中Code_A字段按照下列规则替换为sheet2表数据中对应的Code_B字段。
替换规则:
1)、先按City,Year,Month,MonthSort升序排序,然后根据City,Year,Month,MonthSort匹配对应行进行替换
2)、相同City,Year,Month下,Code_A和Code_B的数量可能不同,如果不同,按照下面子规则替换:
(1)Code_A较多时,多出的Code_A暂时不替换(即sheet1的MonthSort大于sheet2的MonthSort的行)
(2)Code_B较多时,多出的Code_B暂时不替换,但相同City,Year后续的月份可能出现Code_A较多的情况,此时将前面月份多出的Code_B按先后顺序替换多出的Code_A。(先多出的Code_B先替换,且多出的Code_B只替换更大月份的Code_A)
(3)最终还剩余多出的Code_A和Code_B不用参与替换。替换只在同City间发生。
3)、最后保留City,Year,Month,MonthSor,Code_A五个字段,将结果导出成excel。将结果excel命名为“result_1.xlsx”
将脚本命名为“python_2.py”
注意:
结果可参考result_reference.xlsx文件的example页;

数据集可以到https://gitcode.net/as604049322/blog_data中下载。

python_test.xlsx中的数据格式如下:

image-20221001221031021

result_reference.xlsx中的结果数据如下:

image-20221001221116987

题目题意很难看懂,我在认真对照答案后,题意核心点翻译如下:

image-20221001221236077

解题

下面我们解决本题,首先读取并合并数据:

import pandas as pd

excel = pd.ExcelFile("python-test.xlsx")
df1 = excel.parse(0)
df2 = excel.parse(1)
df = df1.merge(df2, how="outer", on=['City', 'Year', 'Month', 'MonthSort'])
df.sort_values(['City', 'Year', 'Month', 'MonthSort'],
               ignore_index=True, inplace=True)
df

image-20221001221600515

然后一个遍历搞定:

for city, df_split in df.groupby("City"):
    idx1 = df_split.index[df_split.Code_A.isnull()].values
    idx2 = df_split.index[df_split.Code_B.isnull()].values
    i, j = 0, 0
    while i < idx1.shape[0] and j < idx2.shape[0]:
        if df_split.loc[idx1[i], "Month"] < df_split.loc[idx2[j], "Month"]:
            df.loc[idx2[j], "Code_B"] = df_split.loc[idx1[i], "Code_B"]
            i += 1
        j += 1
df.dropna(subset=["Code_A"], inplace=True)
df.Code_A = df.Code_B.fillna(df.Code_A)
df = df.drop(columns=["Code_B"]).reset_index(drop=True)
df.to_excel("result_1.xlsx", index=False)
df

image-20221001221652836

经确认结果无误:

df2 = pd.read_excel("result_reference.xlsx")
print(df.compare(df2))
Empty DataFrame
Columns: []
Index: []

对比差异为空。

然后按要求将以下完整代码保存到python_2.py文件中:

import pandas as pd

excel = pd.ExcelFile("python-test.xlsx")
df1 = excel.parse(0)
df2 = excel.parse(1)
df = df1.merge(df2, how="outer", on=['City', 'Year', 'Month', 'MonthSort'])
df.sort_values(['City', 'Year', 'Month', 'MonthSort'],
               ignore_index=True, inplace=True)
for city, df_split in df.groupby("City"):
    idx1 = df_split.index[df_split.Code_A.isnull()].values
    idx2 = df_split.index[df_split.Code_B.isnull()].values
    i, j = 0, 0
    while i < idx1.shape[0] and j < idx2.shape[0]:
        if df_split.loc[idx1[i], "Month"] < df_split.loc[idx2[j], "Month"]:
            df.loc[idx2[j], "Code_B"] = df_split.loc[idx1[i], "Code_B"]
            i += 1
        j += 1
df.dropna(subset=["Code_A"], inplace=True)
df.Code_A = df.Code_B.fillna(df.Code_A)
df = df.drop(columns=["Code_B"]).reset_index(drop=True)
df.to_excel("result_1.xlsx", index=False)

标注数据整理

需求

背景:
有一张图片, 其上用矩形框标注出数目不定的若干对象. 每个对象有若干属性, 每个属性值为预定的值之一.
要求解析输入数据, 适配成人和程序方便阅读的csv格式, 打印或保存结果.

输入:
输入数据有两个, assignment描述的是标注需求, annotations描述的是标注结果.

输入数据示例如下:

assignment_sample = {            # assignment 顶层为python字典
    'type': 'rectangle',         # 标注对象工具类型, 题目中只有矩形框一种, 可忽略
    'properties': [{             # 要求标注对象的属性. 数组, 其中每个字典描述一个属性, 数目不定
        'id': 1,                 # 此属性项的唯一id
        'name': '对象类型',      # 此属性项的名称
        'items': ['行人', '车'], # 属性值备选项. 对应annotations中的属性值为其中之一.
    }],
}

annotations_sample = [{          # 标注结果, 数组, 其中每个元素描述一个标注对象. 图里画了多少框, 就有多少个
    'object_id': 1,              # 一张图中标注对象的唯一id
    'rectangle': {               # 题目只有矩形框
        'x1': 100,               # 框的坐标, 整数. (x1, y1)是框的左上角点, (x2, y2)是框的右下角点. (图片左上角坐标为(0, 0))
        'y1': 10,
        'x2': 201,
        'y2': 250,
    },
    'properties': [{             # 每项表示一个属性. 每个属性一定有值, 所以其长度等于assignment中properties的长度 
        'property_id': 1,        # 对应assignment['properties']中的'id', 表示此项是哪个属性项. 
        'value': '行人',         # 标注的属性值
    }]
}]

输出:
csv格式, 每行代表一个对象, 要求输出每个对象的object_id和属性值.
第一行为列头, 第一个字段是object_id, 余下每个字段是每个属性的name (如示例中的"对象类型")
下面每个对象顺序无要求, object_id对应正确即可.
直接print出结果或保存为文件均可.

上面简单示例的输出结果应为:
object_id,对象类型
1,行人

提示: 用python自带的csv.DictWriter.
可参考官方文档: https://docs.python.org/3/library/csv.html
(用手动拼接字符串的方式生成结构化数据是巨大的减分项)

进阶需求, 可任选:

1. 输出结果中添加一个字段, 表示框的面积
   例如: object_id,对象类型,面积
    1,行人,3000
2. 额外打印出每个"对象类型"的框的个数统计, 格式任意
   例如: object_id,对象类型,面积,个数
    1,行人,3000,1

数据工程师测试题.py中待完整的代码:

def convert_to_csv(assignment, annotations):
    # 请补全此函数
    raise NotImplementedError


# 程序从这里开始执行
if __name__ == '__main__':
    # 输入数据不要改
    assignment = {
        'type': 'rectangle',
        'properties': [{
            'id': 1,
            'name': '对象类型',
            'items': ['小汽车', '大汽车', '人', '自行车'],
        }, {
            'id': 2,
            'name': '是否清晰',
            'items': ['是', '否'],
        }, {
            'id': 3,
            'name': '是否完整',
            'items': ['完整', '不完整'],
        }],
    }

    annotations = [{
        'object_id': 100,
        'rectangle': {
            'x1': 100,
            'y1': 100,
            'x2': 150,
            'y2': 150,
        },
        'properties': [{
            'property_id': 1,
            'value': '自行车',
        }, {
            'property_id': 2,
            'value': '是',
        }, {
            'property_id': 3,
            'value': '完整',
        }]
    }, {
        'object_id': 101,
        'rectangle': {
            'x1': 200,
            'y1': 100,
            'x2': 450,
            'y2': 150,
        },
        'properties': [{
            'property_id': 1,
            'value': '大汽车',
        }, {
            'property_id': 2,
            'value': '是',
        }, {
            'property_id': 3,
            'value': '不完整',
        }]
    }, {
        'object_id': 102,
        'rectangle': {
            'x1': 100,
            'y1': 150,
            'x2': 120,
            'y2': 150,
        },
        'properties': [{
            'property_id': 3,
            'value': '完整',
        }, {
            'property_id': 1,
            'value': '大汽车',
        }, {
            'property_id': 2,
            'value': '否',
        }]
    }, {
        'object_id': 103,
        'rectangle': {
            'x1': 300,
            'y1': 100,
            'x2': 400,
            'y2': 200,
        },
        'properties': [{
            'property_id': 3,
            'value': '完整',
        }, {
            'property_id': 1,
            'value': '人',
        }, {
            'property_id': 2,
            'value': '是',
        }]
    }]

    convert_to_csv(assignment, annotations)

解题

实现函数为:

from collections import Counter
import csv
from io import StringIO

def convert_to_csv(assignment, annotations):
    # 请补全此函数
    properties = {row["id"]: row["name"] for row in assignment["properties"]}
    data = []
    c = Counter()
    for annotation in annotations:
        row = {"object_id": annotation["object_id"]}
        for propertie in annotation["properties"]:
            row[properties[propertie["property_id"]]] = propertie["value"]
        p = annotation["rectangle"]
        row["面积"] = (p["x2"]-p["x1"])*(p["y2"]-p["y1"])
        c[row["对象类型"]] += 1
        data.append(row)
    for row in data:
        row["个数"] = c[row["对象类型"]]
    csvfile = StringIO()
    writer = csv.DictWriter(csvfile, fieldnames=data[0].keys())
    writer.writeheader()
    for row in data:
        writer.writerow(row)
    csvfile.seek(0)
    print(csvfile.read())

结果:

object_id,对象类型,是否清晰,是否完整,面积,个数
100,自行车,是,完整,2500,1
101,大汽车,是,不完整,12500,2
102,大汽车,否,完整,0,2
103,人,是,完整,10000,1

相关文章:

  • 节日网页HTML代码 学生网页课程设计期末作业下载 清明节大学生网页设计制作成品下载 DW节日网页作业代码下载
  • 生命在于折腾——某国外cms代码审计
  • 『从零开始学小程序』媒体组件audio组件
  • [HJ73 计算日期到天数转换]
  • FastDFS数据迁移
  • Java Web 10 JSP 10.3 JSP 原理
  • extern “C“
  • 基于ARM9平台的网络可视电话设计
  • [Qualcomm][GPIO]高通芯片引脚相关知识记录
  • 平衡二叉树之红黑树
  • 【python-Unet】计算机视觉~舌象舌头图片分割~机器学习
  • 【云原生】Hive on k8s 环境部署
  • 一起来学Kotlin:概念:1. Kotlin ArrayListOf 的使用案例
  • 基于MATLAB/GUI的自组网仿真平台,对比leach,ADOV协议
  • 四、哈希表相关题目
  • 2017-09-12 前端日报
  • Android 控件背景颜色处理
  • fetch 从初识到应用
  • hadoop集群管理系统搭建规划说明
  • JavaScript设计模式系列一:工厂模式
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • Promise面试题,控制异步流程
  • Python语法速览与机器学习开发环境搭建
  • React Native移动开发实战-3-实现页面间的数据传递
  • React Transition Group -- Transition 组件
  • redis学习笔记(三):列表、集合、有序集合
  • windows下使用nginx调试简介
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 从零开始的无人驾驶 1
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 那些被忽略的 JavaScript 数组方法细节
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端性能优化--懒加载和预加载
  • 学习使用ExpressJS 4.0中的新Router
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 湖北分布式智能数据采集方法有哪些?
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #Lua:Lua调用C++生成的DLL库
  • (3)llvm ir转换过程
  • (笔试题)合法字符串
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • .net core 依赖注入的基本用发
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET/C# 的字符串暂存池
  • .NetCore 如何动态路由
  • .NET值类型变量“活”在哪?
  • .vimrc php,修改home目录下的.vimrc文件,vim配置php高亮显示
  • @RequestBody与@ModelAttribute
  • @我的前任是个极品 微博分析
  • [.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序...
  • [AIGC codze] Kafka 的 rebalance 机制