pandas/python 一个实战小案例

上次写坦克游戏的时候,接触了一点pandas,当时只是简单了解了一下如何遍历行和列并获取值来替换图片,想更多了解pandas。正好有一些数据需要筛选,试试能不能用通过代码实现。虽然总的来说不复杂,但由于原始数据在命名、分类上的严重不规范,特殊情况太多,整个筛选对于初接触pandas来说,基本处于在网上查一步学一步写一步的状态,最后整理如下:

一、pandas.set_option,让pandas打印更整齐

先来解决一下pandas的打印在控制台的显示问题,先导入pandas模块,读取一个店铺销售报表,然后直接打印: 

import pandas

data = pandas.read_excel('6131店铺.xlsx')

print(data)

 

可以看出来,这个图片中重要的信息都没显示出来,而且数据和列标题对应不工整,看着很费劲。通过pandas.set_option来进行设置。

import pandas

pandas.set_option('display.width', None)
pandas.set_option('display.max_columns', None)
pandas.set_option('display.unicode.east_asian_width', True)

data = pandas.read_excel('6131店铺.xlsx')

print(data)

pandas.set_option的用法是:pandas.set_option(key, value),但是这个key有好多好多,这里用到三个:

1、设定打印显示的总宽

pandas.set_option('display.width', None):大概意思呢就是定义pycharm下面控制台能显示的总宽度,None是有多宽就显示多宽。也可以输入整数来定义宽度。

2、设定打印显示的总列数

pandas.set_option('display.max_columns', None):定义显示最大列的数量,如果选择None,就是把所有的列都显示出来,我后来设定为10列,基本重要的信息应该都可以显示出来了。

3、设定pandas打印显示列对齐

pandas.set_option('display.unicode.east_asian_width', True):这个的意思是按照东亚地区的字符宽度来进行右对齐,实际呢这个运行之后并不能达到理想的对齐效果。还需要进行设置。

打开pycharm设置-编辑器-配色方案-控制台字体,需要注意的是要在上图(使用控制台字体) 那里选择,在下面(仅显示等宽字体)那里取消选择,这样就可以再字体位置选择电脑安装的字体,但不是所有字体都能够实现工整对齐,秘诀就是打印一个表格,完了挨个字体尝试,总有一款字体属于你。

这就很整齐了吧,整个数据表列数有点多,在实际过程中应该不需要把全部的列都打印出来,我这里采用的是pandas.set_option('display.max_columns', 10),有10列的数据,应该可以实现关键数据查看了。

二、载入数据

import pandas

pandas.set_option('display.width', None)
pandas.set_option('display.max_columns', 10)
pandas.set_option('display.unicode.east_asian_width', True)

data = pandas.read_excel('6131店铺.xlsx', sheet_name=0, dtype={'条码': str})
data = data[['货号', '条码', '品名', '分类',  '净销售额', '销售数量', '规格']]

print(data)
1、读取excel两种格式文件:xls和xlsx

pandas.read_excel读取excel文件,这里读取的是xlsx后缀的excel,原来文件是老版的xls后缀,查阅后才知道如果要读取xls后缀的文件,需要再安装xlrd包,而且在参数中需要加上engine='xlrd',但是在后期我想在原文件里写入数据的时候仍然提示错误,估计还需要别的方式,还是采用把所有文件都转存xlsx后缀的吧。

2、指定读取具体sheet表单:

sheet_name=0是指excel文件的第一个sheet,可以是按照顺序的数字,也可以是'sheet名字'。

3、条码类型转换:

dtype={'条码': str},这个是后来在筛选数据时出现问题才加的,有可能pandas将条码按照科学计数的方式给读入了,造成筛选报错,后来网上查阅通过dtype定义条码列为str数据解决了。

4、筛选出必要数据

在实际数据分析中,这里只选择了货号、条码等7列有用的数据,那些日期啥的都去掉,应该是能让运算更快一些吧。 打印效果如下:

 三、准备开始筛选

1、建立源文件列表

建一个文件列表,将所有需要筛选的文件都放到这个列表里,然后通过for循环遍历,逐个筛选处理,这里为了方便测试,就先只放了一个文件。

2、建立筛选结果字典

准备一个存放筛选结果的字典,将每一步筛选出的结果逐步加入到这个字典对应的数据中,并最终形成一个新的数据表。 

import pandas

pandas.set_option('display.width', None)
pandas.set_option('display.max_columns', 10)
pandas.set_option('display.unicode.east_asian_width', True)

data_list = ['6131店铺.xlsx']

result_data = {
    '店铺名称': [],
    '总销售额': [],
    '总销售数量': [],
    '进口总销售额': [],
    '进口总销售数量': [],
    '进口10元以上销售额': [],
    '进口10元以上销售数量': [],
    'BAND销售额': [],
    'BAND销售数量': []
}

for i in range(len(data_list)):
    data = pandas.read_excel(data_list[i], sheet_name=0, dtype={'条码': str})
    data = data[['货号', '条码', '品名', '分类',  '净销售额', '销售数量', '规格']]

    print(data)
3、筛选出规定品类所有品牌商品的总销售额及总销售数量:

第一步:筛选出data中品名列含关键字的数据,和品名中不含关键字的,但是分类中含关键字的数据,然后将二者合并。

    data1 = data[data['品名'].str.contains('关键字1')]
    data2 = data[~data['品名'].str.contains('关键字1') & data['分类'].str.contains('关键字1')]

    data_frame = pandas.concat([data1, data2], axis=0)

通过数据表  名称['列名']  来确定一列的数据,调用str.contains('关键字')得到的是所有包含该关键字的数据并传递给data1。反向选择,也就是不包含采用反义符  ~  ,而不是not,并列的 与 用的不是and,而是  &   。

第二步:链接两个数据表:pandas.concat()把两个数据链接起来,这里参数  axis=0是把后面的数据放到前面数据最后一行的下面,如果要放到前面数据最后一列的后面,则要改成  axis=1  。

第三步:特殊条件剔除:建立了三个特殊条件列表,list1是极个别店铺存在的数据,而且没有什么规律,单独在货号中剔除。list2是有一定规律的品牌,可以通过品名列筛选剔除。list3是后面剔除国产商品时使用。

remove_list1 = [2995235, 2995336]
remove_list2 = ['江', '锐', '屈', '德亚', '山楂']
remove_list3 = ['69', '2000']

 分别遍历list1和list2,调用drop函数删除包含条件的行。这里需要注意的是条件判定后面需要有一个  .index  来获取条件下的行号,再通过drop删除。

然后是通过列调用sum()函数求和,再用round函数四舍五入保留小数点后面两位。得到的数据汇总到result_data。

为了后期的抽验核对,将该数据写入原数据表,用with pandas.ExcelWriter() as writer:语句,网上说的是可以不用管文件的打开和关闭。括号中间的参数首先是要写入的文件路径,mode= 'a',是追加的意思,我理解就是在文件中新建一个sheet吧,要不是不是就把初始文件给覆盖了呢?

to_excel是写入,括号里面的writer是固定写法,后面的sheet_name是指新建一个sheet表单的名字。

if_sheet_exists='replace'是指如果这个新建的表单在原文件中存在,那么就覆盖,否则会报错。

    for r1 in remove_list1:
        data_frame = data_frame.drop(data_frame[data_frame['货号'] == r1].index)
    for r2 in remove_list2:
        data_frame = data_frame.drop(data_frame[data_frame['品名'].str.contains(r2)].index)

    total_sales = round(data_frame['净销售额'].sum(), 2)
    total_quantity = round(data_frame['销售数量'].sum())

    result_data['店铺名称'].append(data_list[i])
    result_data['总销售额'].append(total_sales)
    result_data['总销售数量'].append(total_quantity)

    with pandas.ExcelWriter(data_list[i], if_sheet_exists='replace', mode='a') as writer:
        data_frame.to_excel(writer, sheet_name='销售总表')
4、筛选进口产品销售数据
    for r3 in remove_list3:
        data_frame = data_frame[data_frame['条码'].str.startswith(r3) == False]

    total_sales1 = round(data_frame['净销售额'].sum(), 2)
    total_quantity1 = round(data_frame['销售数量'].sum())

    result_data['进口总销售额'].append(total_sales1)
    result_data['进口总销售数量'].append(total_quantity1)

    with pandas.ExcelWriter(data_list[i], if_sheet_exists='replace', mode='a') as writer:
        data_imp.to_excel(writer, sheet_name='进口销售表')

这一步是遍历list3,删除掉以条码69开头的国产商品和条码以2000开头自建条码国产商品。意外的是要留下非69和2000开头的数据,用反义符号  ~  却报错了,not也不行,这中间也尝试了用drop删除条码69开头的和条码2000开头的数据,大概是因为原始数据条码列里有空值,也报错了,也尝试了给空值填上数据也不行,最后是这个奇葩的 == False才解决。

5、后面的就基本都一样了,最后的全部文件:

import pandas

pandas.set_option('display.max_columns', 10)
pandas.set_option('display.width', None)
pandas.set_option('display.unicode.east_asian_width', True)

data_list = ['6131店铺.xlsx', '6132店铺.xlsx', '6176店铺.xlsx', '6201店铺.xlsx', '6257店铺.xlsx',
             '6263店铺.xlsx', '6274店铺.xlsx', '6382店铺.xlsx', '6387店铺.xlsx', '6388店铺.xlsx']

result_data = {
    '店铺名称': [],
    '总销售额': [],
    '总销售数量': [],
    '进口总销售额': [],
    '进口总销售数量': [],
    '进口10元以上销售额': [],
    '进口10元以上销售数量': [],
    'BAND销售额': [],
    'BAND销售数量': []
}

remove_list1 = [2995235, 2995336]
remove_list2 = ['江', '锐', '屈', '德亚', '山楂']
remove_list3 = ['69', '2000']

for i in range(len(data_list)):
    data = pandas.read_excel(data_list[i], sheet_name=0, dtype={'条码': str})
    data = data[['货号', '条码', '品名', '分类',  '净销售额', '销售数量', '规格']]

    data1 = data[data['品名'].str.contains('关键字1')]
    data2 = data[~data['品名'].str.contains('关键字1') & data['分类'].str.contains('关键字1')]

    data_frame = pandas.concat([data1, data2])

    for r1 in remove_list1:
        data_frame = data_frame.drop(data_frame[data_frame['货号'] == r1].index)
    for r2 in remove_list2:
        data_frame = data_frame.drop(data_frame[data_frame['品名'].str.contains(r2)].index)

    total_sales = round(data_frame['净销售额'].sum(), 2)
    total_quantity = round(data_frame['销售数量'].sum())

    result_data['店铺名称'].append(data_list[i])
    result_data['总销售额'].append(total_sales)
    result_data['总销售数量'].append(total_quantity)

    # with pandas.ExcelWriter(data_list[i], if_sheet_exists='replace', mode='a') as writer:
    #     data_frame.to_excel(writer, sheet_name='销售总表')

    for r3 in remove_list3:
        data_frame = data_frame[data_frame['条码'].str.startswith(r3) == False]

    total_sales1 = round(data_frame['净销售额'].sum(), 2)
    total_quantity1 = round(data_frame['销售数量'].sum())

    result_data['进口总销售额'].append(total_sales1)
    result_data['进口总销售数量'].append(total_quantity1)

    # with pandas.ExcelWriter(data_list[i], if_sheet_exists='replace', mode='a') as writer:
    #     data_imp.to_excel(writer, sheet_name='进口销售表')

    data_imp_high = data_frame[data_frame['净销售额'] / data_frame['销售数量'] >= 10]
    total_sales2 = round(data_imp_high['净销售额'].sum(), 2)
    total_quantity2 = round(data_imp_high['销售数量'].sum())

    result_data['进口10元以上销售额'].append(total_sales2)
    result_data['进口10元以上销售数量'].append(total_quantity2)

    data_band = data_frame[data_frame['品名'].str.contains('BAND')]
    total_sales3 = round(data_band['净销售额'].sum(), 2)
    total_quantity3 = round(data_band['销售数量'].sum())

    result_data['BAND销售额'].append(total_sales3)
    result_data['BAND销售数量'].append(total_quantity3)

    # with pandas.ExcelWriter(data_list[i], if_sheet_exists='replace', mode='a') as writer:
    #     data_band.to_excel(writer, sheet_name='BAND销售表')

df = pandas.DataFrame(result_data)
df.to_excel('result.xlsx')


print(df)

通过pandas.DataFrame(result_data)将结果转成数据表,并写入新的excel文件result.xlsx,打开后结果:

哈哈,大概有100多个数据表吧,就不用一个个手动筛啦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/556731.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何训练猫出门不害怕:耐心做好这些训练,轻松get能溜的小猫

一般我们外出见到的都是遛狗的,溜猫的相对少见,一方面是因为猫咪是喜欢安静独处的小动物,另一方面是糟乱的环境也容易引起猫咪的应激。对于是否应该“溜猫”,有两个极端的阵营。一些铲屎官认为应尊重猫的天性,胆小不爱…

如何使用AI写作扩写文章?看完这篇学会扩写

如何使用AI写作扩写文章?在数字化时代的浪潮下,人工智能(AI)已经深入渗透到我们生活的各个领域,其中,AI写作扩写技术更是以其高效、便捷的特点受到了广大用户的青睐。它不仅极大提升了写作效率,…

Leetcode算法训练日记 | day29

一、递增子序列 1.题目 Leetcode:第 491 题 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素,如出现两个整数相等&…

硬件?、嘉立创EDA画PCB规则设计

1、打开规则设计 设置单位为mil 点击全部 将安全距离设置为8mil,这个8mil是目前很多生产PCB的工厂可以做的,如果距离设置的更小也就是性能要求更高,相应的生产成本也高元件到元件的距离设置为20mil 2、设置导线的宽度规则,可以对v…

第G6周:CycleGAN实践

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 一、CycleGAN原理 (一)CycleGAN的原理结构: CycleGAN(循环生成对抗网络)是一种生成对抗网络&…

思维导图软件Xmind for Mac 中文激活版 支持M

XMind是一款非常受欢迎的思维导图软件,它应用了Eclipse RCP软件架构,注重易用性、高效性和稳定性,致力于帮助用户提高生产率。 Xmind for Mac 中文激活版下载 XMind的程序主体由一组插件构成,包括一个核心主程序插件、一组Eclipse…

文件后缀变成.halo? 如何恢复重要数据

.halo 勒索病毒是什么? .halo勒索病毒是一种恶意软件,属于勒索软件(Ransomware)的一种。这种病毒会加密用户计算机上的文件,并要求受害者支付赎金才能获取解密密钥,从而恢复被加密的文件。勒索软件通常会通…

力扣(leetcode) 42. 接雨水 (带你逐步思考)

力扣(leetcode) 42. 接雨水 (带你逐步思考) 链接:https://leetcode.cn/problems/trapping-rain-water/ 难度:hard 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多…

【方便 | 重要】#LLM入门 | Agent | langchain | RAG # 3.7_代理Agent,使用langchain自带agent完成任务

大型语言模型(LLMs)虽强大,但在逻辑推理、计算和外部信息检索方面能力有限,不如基础计算机程序。例如,LLMs处理简单计算或最新事件查询时可能不准确,因为它们仅基于预训练数据。LangChain框架通过“代理”(…

机器学习在安全领域的应用:从大数据中识别潜在安全威胁

🧑 作者简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向的学习指导…

Ubuntu20.04 ISAAC SIM仿真下载使用流程(4.16笔记补充)

机器:华硕天选X2024 显卡:4060Ti ubuntu20.04 安装显卡驱动版本:525.85.05 参考: What Is Isaac Sim? — Omniverse IsaacSim latest documentationIsaac sim Cache 2023.2.3 did not work_isaac cache stopped-CSDN博客 Is…

LeetCode in Python 704. Binary Search (二分查找)

二分查找是一种高效的查询方法&#xff0c;时间复杂度为O(nlogn)&#xff0c;本文给出二分查找的代码实现。 示例&#xff1a; 代码&#xff1a; class Solution:def search(self, nums, target):l, r 0, len(nums) - 1while l < r:mid (l r) // 2if nums[mid] > ta…

C++11 数据结构1 线性表的概念,线性表的顺序存储,实现,测试

一 线性表的概念 线性结构是一种最简单且常用的数据结构。 线性结构的基本特点是节点之间满足线性关系。 本章讨论的动态数组、链表、栈、队列都属于线性结构。 他们的共同之处&#xff0c;是节点中有且只有一个开始节点和终端节点。按这种关系&#xff0c;可以把它们的所有…

MC9S12A64 程序烧写方法

前言 工作需要对MC9S12A64 单片机进行程序烧写。 资料 MC9S12A64 单片机前身属于 飞思卡尔半导体&#xff0c;后来被恩智浦收购&#xff0c;现在属于NXP&#xff1b; MC9S12A64 属于16位S12系列&#xff1b;MC9S12 又叫 HCS12。 数据手册下载连接 S12D_16位微控制器 | N…

[大模型]TransNormerLLM-7B 接入 LangChain 搭建知识库助手

TransNormerLLM-7B 接入 LangChain 搭建知识库助手 环境准备 在 autodl 平台中租赁一个 3090/4090 等 24G 显存的显卡机器&#xff0c;如下图所示镜像选择 PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 接下来打开刚刚租用服务器的 JupyterLab&#xff0c;并且打开其…

简单实用的备忘录小工具 记事提醒备忘效果超好

在这个信息爆炸的时代&#xff0c;我们每个人都需要处理大量的信息和任务。有时候&#xff0c;繁忙的生活和工作会让我们感到压力山大。幸运的是&#xff0c;现在有很多简单实用的软件工具&#xff0c;像得力的小助手一样&#xff0c;帮助我们整理思绪&#xff0c;提高效率&…

Redis系列1:深刻理解高性能Redis的本质

1 背景 分布式系统绕不开的核心之一的就是数据缓存&#xff0c;有了缓存的支撑&#xff0c;系统的整体吞吐量会有很大的提升。通过使用缓存&#xff0c;我们把频繁查询的数据由磁盘调度到缓存中&#xff0c;保证数据的高效率读写。 当然&#xff0c;除了在内存内运行还远远不够…

Docker 和 Podman的区别

文章目录 Docker 和 Podman的区别安装架构和特权要求运行容器方面安全性(root的权限)镜像管理方面命令方面Docker常用命令Podman常用命令 Docker 和 Podman的区别 安装 Docker安装&#xff1a;官方文档 Podman安装&#xff1a;官方文档 架构和特权要求 Docker使用client-se…

11、电科院FTU检测标准学习笔记-越限及告警上送功能

作者简介&#xff1a; 本人从事电力系统多年&#xff0c;岗位包含研发&#xff0c;测试&#xff0c;工程等&#xff0c;具有丰富的经验 在配电自动化验收测试以及电科院测试中&#xff0c;本人全程参与&#xff0c;积累了不少现场的经验 ———————————————————…

git 快问快答

我在实习的时候&#xff0c;是用本地开发&#xff0c;然后 push 到 GitHub 上&#xff0c;之后再从 Linux 服务器上拉 GitHub 代码&#xff0c;然后就可以了。一般程序是在 Linux 服务器上执行的&#xff0c;我当时使用过用 Linux 提供的命令来进行简单的性能排查。 在面试的时…