叁拾- Pandas 整理某些原始数据格式 - 类交叉表式生成报表的数据帧处理 以及中括号的妙处

1. 写数据处理类 Python 代码的工具

当然就是鼎鼎大名的朱庇特了!

可以先把代码在这里运行,直接查看结果,再把完成的代码 Copy 到工程上,就省去往来调试的麻烦了。

Windows 下直接下载安装就可以了。

2. Pandas 读取 Excel 是怎样的呢?

我们现在有两个 Shit:

Sheet1

Sheet2

那么从 Pandas 导入这两个 Sheet 会怎样的呢?

明显从 Excel 表的左上侧读取

在什么都不设置的情况下,Pandas 是默认从 Excel 表的最左上侧读取的,而不是读取第一个有数据的行和列。

3. 数据源

数据源

其中第4行是日期标识,

第5行是字段内容标识

4. 转换目标格式

目标转换格式

5. 工作前需注意事项

程序语言与日常的数数不一样,是从 0 开始的,而不是从 1 开始的(但我其实 VB 某些数据类型返回是从 1 开始数的,我也不知道是什么心态了)。

所以注意,Pandas 中 数据帧的行和列的位置跟 数据源 的行号是不一样的!

6. 简单处理开始

因为本文只是简单处理数据格式调整,未涉及数据内容处理,相关后事请看后文。

6.1 准备

# 引入包
import pandas as pd
import time
import numpy as np

# 此处引入数据
# 是的,我是 Windows 用户,怎么了!?不给么!?哼!
dfWeeklySales=pd.read_excel('C:\\Users\\BerryCui\\Desktop\\TempData\\20200110\\qq.xlsx',header = None)

# 此处初始化数据
arrSales=[5,10,15]
arrTXN=[6,11,16]
arrATV=[7,12,17]
arrTime=dfWeeklySales.iloc[3][[5,10,15]].tolist()
arrTime
intYear=2019
intDayNum=3

# 此处定义一个空白的数据帧存放数据
dfShow=pd.DataFrame(columns=['Channel','CN','Store','Market','Act Sales','Act TXN','Act ATV','Day','Year'])

上述代码描述了如何初始化位置参数,当然实际上面对的表格可能并不是固定格式(即相应数据内容并不固定行)的,但本文只针对固定格式进行说明。

(其实判断对应内容位置的代码在别的文章,别随便告诉人)

另外还存设定了一个空白的数据帧以存放整理后的数据。

6.2 转换

开始了哦,别眨眼了哦!

for intI in range(intDayNum):
    dfTmp=pd.DataFrame(dfWeeklySales[~dfWeeklySales.iloc[:,[3]].isnull().values &
                                     (dfWeeklySales.iloc[:,[3]]!='Store').values].iloc[:,[1,2,3,4,arrSales[intI],arrTXN[intI],arrATV[intI]]])
    dfTmp.columns=['Channel','CN','Store','Market','Act Sales','Act TXN','Act ATV']
    dfTmp.insert(len(dfTmp.columns),'Day',arrTime[intI])
    dfTmp.insert(len(dfTmp.columns),'Year',intYear)
    dfShow=dfShow.append(dfTmp,ignore_index=True)

好了,完事了。

6.3 关键解释

6.3.1 关于两个中括号(方括号)

其实如果有学过 R语言 的人,估计也会经历类似的伤心事。

上述代码中:

dfWeeklySales.iloc[3][[5,10,15]]

为什么会有 一个中括号里再包含一个中括号呢?

原因参看文章 Pandas中loc,iloc与直接切片的区别 :

直接索引索引的是列,方口号里面的内容一般是列索引名。也可以接受一个列名组成的list来接受多个列名。

6.3.2 获取数据帧中非空数据

对于 Pandas 空数据处理、数据过滤、查找空值等方法在基础教程里面有很多,一下为查找第4列非空的数据:

dfWeeklySales[~dfWeeklySales.iloc[:,[3]].isnull().values]

其中 ~dfWeeklySales.iloc[:,[3]].isnull().values 为第4列非空的行,~ 的意思是否。

那为什么要加 .values 呢?

.values 的意思是从 数据帧转换为:numpy.ndarray 类型。

如果你不是放 numpy.ndarray 到中括号中,而是放 数据帧(pandas.core.frame.DataFrame),例如:

dfTT=pd.DataFrame([[True,False,True,True,True,True],
                   [True,False,True,True,True,True],
                   [True,False,True,True,True,True],
                   [True,False,True,True,True,True]])
dfWeeklySales[dfTT]

你将会得到:

前10行数据

其实,就是在原数据帧(dfWeeklySales)中,对应新数据帧(dfTT)内容为 True 的数据。

是不是很简单呢~

6.3.3 原理

for 循环一共循环了3次(定义数据源只有3天的数据,提取数据表头内容的方法将在后续文章撰写)。

然后分别把3天的 'Act Sales','Act TXN','Act ATV' 以及数据归属放到一个临时的数据帧。

再把每天的数据帧合并到一起就行了。

7. 关于后事

三世书之所以重要,即需了解任何人事物的前世、今生、来世。

事物的前世包括它的形成、来源、意义等;

事物的今生包括它现在的形式、组成、链接外在的链接接口等;

事物的来世包括它可能引起的后果、即将前往何处、会与谁进行交互等。

了解前世需要相关经验,了解今生需要知识,了解来世需要用意识,我们必须靠努力的不断学习,不断充实自己,才能得到我们想要的结果,不然我们只能不断在原地迷惘,进而堕入修罗之道。

之后就把前期做好的表头查找形式、以及部分技巧继续存续下来,以便能让他们更好的保存下来,对自己的未来以及未来的你能有更大的裨益。

别误会,我不是雷锋,我只是崔秉龙,最后这一段纯粹是凑字数。

刚好4000字了,我好累啊。