目录:
- 问题1:透视与多层索引类
- 问题2:文本数据处理类
- 问题3:条件赋值
问题1:透视与多层索引类
有一个朋友,提出了这样的疑问,类似长表变宽表的题,看了下大致需要用到透视和多层索引的处理。
我们来看一下详细需求:
看到这个,我们用Excel其实很好处理,直接 数据透视表 拖拽就行,参考:
Excel直接上透视表
那么,在Pandas里怎么实现呢?
可以看到这位朋友方向是对的,但是在参数设置上稍微有点问题,应该这样实现:
代码语言:javascript复制import pandas as pd
# 大家直接复制下面输出的数据然后演示即可
df = pd.read_clipboard()
df
原始数据:
月份 | 编号 | 单价 | 数量 | |
---|---|---|---|---|
0 | 1月 | A01 | 10 | 1 |
1 | 1月 | A02 | 10 | 2 |
2 | 1月 | A03 | 10 | 3 |
3 | 1月 | A04 | 10 | 4 |
4 | 2月 | A01 | 3 | 1 |
5 | 2月 | A02 | 4 | 2 |
6 | 3月 | A01 | 3 | 1 |
7 | 3月 | A02 | 4 | 2 |
8 | 3月 | A03 | 5 | 3 |
9 | 3月 | A04 | 6 | 4 |
10 | 3月 | A05 | 7 | 5 |
# 透视过程
temp = df.pivot(index='编号',columns='月份',values=['单价','数量'])
temp
输出结果:
这个时候,其实和期望结果还是有点差异,我们期望的是月份下面分单价和数据,而不是单价与数量下面分月份。这个时候,就该我们多层索引
出场了,直接调整索引的level即可。
# 多层索引调整level
data = temp.swaplevel(0,1,axis=1).sort_index(axis=1)
data
输出结果:
你以为到这里就结束了吗?其实不然!
我们看下输出的excel
文档结果,发现存在一行为空的情况,通过查询发现这是Pandas
已知的问题,据说是为了给行索引名字(编号)留的。
怎么处理呢?可以试着去掉行索引名字,然后存csv:
代码语言:javascript复制# 行索引名称去掉
data.index.name=None
data
然后存为csv
文件,发现勉强可以:
data.to_csv('结果.csv',encoding='utf-8-sig')
补充:大家还可以用excel
处理的其他第三方库操作,比如openpyxl
里的delete_rows(3)
删除第三行之类的。
问题2:文本数据处理类
有一个朋友有一些数据,看了下内容大致上姓名-号码-单号组成,但是每个元素部分之间的分隔符并不统一。看了下, 大致可以用pandas
里的extract
来提取。
import pandas as pd
# 读取数据
df = pd.read_excel(r'测试数据.xlsx')
df
测试数据:
信息 | |
---|---|
0 | 小明-185-DEG30V8 |
1 | 小一-138-DEGV22 |
2 | 库里-138-JQCB07 |
3 | 云朵-130-SHYG202613 |
4 | 赛文 133 SHYZ20270 |
5 | 二百君-189-SHYZ2010 |
6 | 皮特-139-SHYG26236 |
7 | 萝卜-189-SHYZ22189 |
8 | 辰哥-156-SHYG29116 |
9 | 可乐-185-SHYG26663 |
10 | 才哥-160 |
这里直接参考《一看就会的Pandas文本数据处理》,用extract
函数方法来进行提取。
df['信息'].str.extract(r'(?P<姓名>[u4e00-u9fa5] ).*?(?P<号码>d ).*?(?P<单号>[A-Z].*)?$')
输出结果:
姓名 | 号码 | 单号 | |
---|---|---|---|
0 | 小明 | 185 | DEG30V8 |
1 | 小一 | 138 | DEGV22 |
2 | 库里 | 138 | JQCB07 |
3 | 云朵 | 130 | SHYG202613 |
4 | 赛文 | 133 | SHYZ20270 |
5 | 二百君 | 189 | SHYZ2010 |
6 | 皮特 | 139 | SHYG26236 |
7 | 萝卜 | 189 | SHYZ22189 |
8 | 辰哥 | 156 | SHYG29116 |
9 | 可乐 | 185 | SHYG26663 |
10 | 才哥 | 160 | NaN |
问题3:条件赋值
有一个朋友需要修改满足条件的数据帧某个字段的值,然后按照预想的方式发现不奏效!
我们简单看下他是怎么操作的:
那是为什么呢?
其实,在['金额']
之前的表达式返回的是DataFrame
数据,[]
方法修改的是这个数据的值,而不是原有的muban
。
我们通过下面的演示让大家熟悉了解一下:
代码语言:javascript复制import pandas as pd
d = {'col1': ['才哥', '财哥'], 'col2': [101, 99]}
df = pd.DataFrame(data=d)
df
案例数据:
col1 | col2 | |
---|---|---|
0 | 才哥 | 101 |
1 | 财哥 | 99 |
我们将col1
为才哥的这行数据的col2
改为100
temp = df[df['col1']=='才哥']
temp['col2'] = 100
输出结果:
col1 | col2 | |
---|---|---|
0 | 才哥 | 100 |
而实际上df
的值没变化
那么,怎么在df
上进行修改呢?直接把[]
里的值放在里面就行了~
df.loc[df['col1']=='才哥', 'col2'] = 100
df
输出结果:
col1 | col2 | |
---|---|---|
0 | 才哥 | 100 |
1 | 财哥 | 99 |
搞定!
以上就是最近在咱们技术交流群里朋友圈讨论的一些问题,相信大家还有更多解法,我这里也只是抛砖引玉。