最近群里出现的3个数据处理需求,如何用Pandas简单实现一下

2021-11-16 11:41:24 浏览数 (1)

目录:

  • 问题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

代码语言:javascript复制
# 透视过程
temp = df.pivot(index='编号',columns='月份',values=['单价','数量'])
temp

输出结果:

这个时候,其实和期望结果还是有点差异,我们期望的是月份下面分单价和数据,而不是单价与数量下面分月份。这个时候,就该我们多层索引出场了,直接调整索引的level即可

代码语言:javascript复制
# 多层索引调整level
data = temp.swaplevel(0,1,axis=1).sort_index(axis=1)
data

输出结果:

你以为到这里就结束了吗?其实不然!

我们看下输出的excel文档结果,发现存在一行为空的情况,通过查询发现这是Pandas已知的问题,据说是为了给行索引名字(编号)留的。

怎么处理呢?可以试着去掉行索引名字,然后存csv

代码语言:javascript复制
# 行索引名称去掉
data.index.name=None
data

然后存为csv文件,发现勉强可以:

代码语言:javascript复制
data.to_csv('结果.csv',encoding='utf-8-sig')

补充:大家还可以用excel处理的其他第三方库操作,比如openpyxl里的delete_rows(3)删除第三行之类的。

问题2:文本数据处理类

有一个朋友有一些数据,看了下内容大致上姓名-号码-单号组成,但是每个元素部分之间的分隔符并不统一。看了下, 大致可以用pandas里的extract来提取。

代码语言:javascript复制
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函数方法来进行提取。

代码语言:javascript复制
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

代码语言:javascript复制
temp = df[df['col1']=='才哥']
temp['col2'] = 100

输出结果:

col1

col2

0

才哥

100

而实际上df的值没变化

那么,怎么在df上进行修改呢?直接把[]里的值放在里面就行了~

代码语言:javascript复制
df.loc[df['col1']=='才哥', 'col2'] = 100
df

输出结果:

col1

col2

0

才哥

100

1

财哥

99

搞定!

以上就是最近在咱们技术交流群里朋友圈讨论的一些问题,相信大家还有更多解法,我这里也只是抛砖引玉。

0 人点赞