一、背景
有这么一个原始数据,如下表:
NO | 日期 | 卡班号码 | 状态 | 使用车型 | 目的站 | 运输总重-KG |
---|---|---|---|---|---|---|
1 | 2020/5/1 | MZZ1001 | 已发 | 2吨卡车 | 杭州 | 1500 |
2 | 2020/5/2 | MZZ1001 | 未发 | 4吨卡车 | 杭州 | 3500 |
3 | 2020/5/3 | MZZ1001 | 已到 | 6吨卡车 | 杭州 | 5500 |
4 | 2020/5/4 | MZZ1001 | 已发 | 8吨卡车 | 杭州 | 7500 |
5 | 2020/5/5 | MZZ1001 | 未发 | 2吨卡车 | 杭州 | 1800 |
6 | 2020/5/1 | MZZ1002 | 已到 | 4吨卡车 | 合肥 | 3800 |
7 | 2020/5/2 | MZZ1002 | 已发 | 6吨卡车 | 合肥 | 5800 |
8 | 2020/5/3 | MZZ1002 | 未发 | 8吨卡车 | 合肥 | 6800 |
10 | 2020/5/5 | MZZ1002 | 已发 | 4吨卡车 | 合肥 | 3600 |
11 | 2020/5/1 | MZZ1003 | 未发 | 6吨卡车 | 大连 | 5600 |
12 | 2020/5/2 | MZZ1003 | 已到 | 8吨卡车 | 大连 | 7800 |
13 | 2020/5/3 | MZZ1003 | 已发 | 2吨卡车 | 大连 | 1200 |
14 | 2020/5/4 | MZZ1003 | 未发 | 4吨卡车 | 大连 | 3500 |
16 | 2020/5/1 | MZZ1004 | 已发 | 8吨卡车 | 青岛 | 7700 |
17 | 2020/5/2 | MZZ1004 | 未发 | 2吨卡车 | 青岛 | 1100 |
18 | 2020/5/3 | MZZ1004 | 已到 | 4吨卡车 | 青岛 | 3500 |
19 | 2020/5/4 | MZZ1004 | 已发 | 6吨卡车 | 青岛 | 5600 |
20 | 2020/5/5 | MZZ1004 | 未发 | 8吨卡车 | 青岛 | 7800 |
想调整格式输出为另外一个表:
卡班号码 | 2020年5月1日 | 2020年5月2日 | 2020年5月3日 | 2020年5月4日 | 2020年5月5日 | |
---|---|---|---|---|---|---|
0 | MZZ1001 | 状态:已发 使用车型:2吨卡车 目的站:杭州 | 状态:未发 使用车型:4吨卡车 目的站:杭州 | 状态:已到 使用车型:6吨卡车 目的站:杭州 | 状态:已发 使用车型:8吨卡车 目的站:杭州 | 状态:未发 使用车型:2吨卡车 目的站:杭州 |
1 | MZZ1002 | 状态:已到 使用车型:4吨卡车 目的站:合肥 | 状态:已发 使用车型:6吨卡车 目的站:合肥 | 状态:未发 使用车型:8吨卡车 目的站:合肥 | 无 | 状态:已发 使用车型:4吨卡车 目的站:合肥 |
2 | MZZ1003 | 状态:未发 使用车型:6吨卡车 目的站:大连 | 状态:已到 使用车型:8吨卡车 目的站:大连 | 状态:已发 使用车型:2吨卡车 目的站:大连 | 状态:未发 使用车型:4吨卡车 目的站:大连 | 无 |
3 | MZZ1004 | 状态:已发 使用车型:8吨卡车 目的站:青岛 | 状态:未发 使用车型:2吨卡车 目的站:青岛 | 状态:已到 使用车型:4吨卡车 目的站:青岛 | 状态:已发 使用车型:6吨卡车 目的站:青岛 | 状态:未发 使用车型:8吨卡车 目的站:青岛 |
二、需求理解
- columns -- 日期
- index -- 卡班号码
- values -- 状态、使用车型、目的站(使用字符串拼接)
三、动手
1.stack & unstack
# 导入包、设定路径
import pandas as pd
import os
import datetime
os.chdir(r'C:\Users\Hider\Desktop\一道stack & pivot_table练习题')
# 读取数据
df = pd.read_excel('data.xlsx', index_col=0)
# 修改日期格式
df['日期'] = pd.to_datetime(df['日期'])
# df['日期'] = df['日期'].dt.strftime('%Y-%m-%d')
df['日期'] = df['日期'].map(lambda x: x.strftime('%Y年%m月%d日'.encode('unicode_escape').decode('utf-8')).encode('utf-8').decode('unicode_escape'))
# 合并数据字段
df['合并'] = '状态:' + df['状态'] + '\n使用车型:' + df['使用车型'] + '\n目的站:' + df['目的站']
# 不需要拼接专门字段时 可利用str.cat拼接
# 结果
result = df[['日期','卡班号码','合并']].set_index(['卡班号码', '日期']).unstack(fill_value='无').reset_index(col_level=1).droplevel(None, axis=1)
# 删除列名
result.columns.name = None
result.to_excel('result.xlsx', index=False)
日期格式莫名报错:
#### 转换日期格式莫名报错 不支持中文 ####
df['日期'] = df['日期'].dt.strftime('%Y年%#m月%#d日')
import time
now_time = time.localtime()
time.strftime('%Y年%m月%d日%H时%M分%S秒'.encode('unicode_escape').decode('utf8'),now_time).encode('utf-8').decode('unicode_escape')
# '2021年11月21日19时04分13秒'
2.pivot
此处只能使用 pivot
透视,不能使用 pivot_table
透视。
# 读取数据
df = pd.read_excel('data.xlsx', index_col=0)
# 修改日期格式
df['日期'] = pd.to_datetime(df['日期'])
# df['日期'] = df['日期'].dt.strftime('%Y-%m-%d')
df['日期'] = df['日期'].map(lambda x: x.strftime('%Y年%m月%d日'.encode('unicode_escape').decode('utf-8')).encode('utf-8').decode('unicode_escape'))
# 定义合并函数
def getValue(df):
return f"状态:{df['状态']}\n使用车型:{df['使用车型']}\n目的站:{df['目的站']}"
# 添加辅助列
df['辅助列'] = df[['状态','使用车型','目的站']].apply(getValue, axis=1)
# 透视
result = df.pivot(index=u'卡班号码', columns=u'日期', values=u'辅助列')
参考:来自Python数据沟通交流群