Pandas数据分析技能总结

Pandas数据分析技能总结


载入和配置常见库

In [1]:

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

In [2]:

# plt.style.use('seaborn')  # 改变图像风格
plt.rcParams['font.family'] = ['Arial Unicode MS', 'Microsoft Yahei', 'SimHei', 'sans-serif']  # 解决中文乱码
# plt.rcParams['axes.unicode_minus'] = False  # simhei黑体字 负号乱码 解决

数据载入

常见数据形式

  • CSV:.csv
  • Excel:.xslx

In [ ]:

# a = pd.read_csv('data/a.csv', encoding='GBK')

# b = pd.read_excel('data/a.xlsx', None)  # 读取所有单元表
# b['Sheet1']  # 读取某一单元表

测试数据

In [3]:

# DataFrame表格

df = pd.DataFrame({
    'name': ['张三','李四','王五','李四','王五','王五','赵六'],
    'chinese': [18, 53, 67, 63, 39, 70, 94],
    'math': [82, 63, 41, 59, 46, 39, 58],
    'english': [68, 52, 90, 86, 60, 98, 64],
    'test': ['一','一','一','二','二','三','一']
})

df

Out[3]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

查询

检查数据

检查列缺失值,和列数据类型是否正常

In [4]:

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7 entries, 0 to 6
Data columns (total 5 columns):
name       7 non-null object
chinese    7 non-null int64
math       7 non-null int64
english    7 non-null int64
test       7 non-null object
dtypes: int64(3), object(2)
memory usage: 360.0+ bytes

快速统计

计算指标,发现异常值

In [5]:

df.describe()

Out[5]:

chinese math english
count 7.000000 7.000000 7.000000
mean 57.714286 55.428571 74.000000
std 24.260491 14.998413 17.281975
min 18.000000 39.000000 52.000000
25% 46.000000 43.500000 62.000000
50% 63.000000 58.000000 68.000000
75% 68.500000 61.000000 88.000000
max 94.000000 82.000000 98.000000

显示前几行和后几行

In [10]:

df.head(3)

Out[10]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90

In [11]:

df.tail(2)

Out[11]:

name chinese math english test
5 王五 70 39 98
6 赵六 94 58 64

查询表格索引和形状

In [9]:

df.index  # 行索引

Out[9]:

RangeIndex(start=0, stop=7, step=1)

In [12]:

df.columns  # 列索引

Out[12]:

Index(['name', 'chinese', 'math', 'english', 'test'], dtype='object')

In [13]:

df.shape  # 形状

Out[13]:

(7, 5)

索引查询和切片查询

In [14]:

df

Out[14]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

In [19]:

# 传统方式,查询列比较方便
df['name']  # 查询多列
df[['name', 'test']]  # 查询多列

# loc方式
# 索引查询
df.loc[:,'name']  # 查询单列
df.loc[[1, 2, 4], ['name', 'chinese', 'test']]  # 多行多列

# 切片查询
df.loc[2:5, 'chinese':'english']  # 查询连续值,loc切片包含结束值

Out[19]:

chinese math english
2 67 41 90
3 63 59 86
4 39 46 60
5 70 39 98

布尔查询(过滤查询)

查询所有语文成绩及格同学的信息

In [21]:

df[df['chinese'] >= 60]

Out[21]:

name chinese math english test
2 王五 67 41 90
3 李四 63 59 86
5 王五 70 39 98
6 赵六 94 58 64

缺失值处理和值类型转换

视图和副本

In [27]:

df2 = df.copy()
df2

Out[27]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

缺失值表示

np.nan系统底层是浮点数

In [28]:

df2.loc[4, 'english'] = np.nan
df2

Out[28]:

name chinese math english test
0 张三 18 82 68.0
1 李四 53 63 52.0
2 王五 67 41 90.0
3 李四 63 59 86.0
4 王五 39 46 NaN
5 王五 70 39 98.0
6 赵六 94 58 64.0

缺失值填充

fillna()

注意:没有修改原数据

In [29]:

df2.fillna(0)

Out[29]:

name chinese math english test
0 张三 18 82 68.0
1 李四 53 63 52.0
2 王五 67 41 90.0
3 李四 63 59 86.0
4 王五 39 46 0.0
5 王五 70 39 98.0
6 赵六 94 58 64.0

值类型转换

astype()

常见类型有:np.int , np.float

字符串类型不能转为数值型

In [39]:

# df2.fillna(0).astype(np.int)  # 报错,只能将非字符串型列转为整型
df2.fillna(0)[['chinese', 'math', 'english']].astype(np.int)
df2[['chinese', 'math', 'english']].fillna(0).astype(np.int)

Out[39]:

chinese math english
0 18 82 68
1 53 63 52
2 67 41 90
3 63 59 86
4 39 46 0
5 70 39 98
6 94 58 64

分组聚合

  • 分组:groupby()
  • 聚合:mean(), size()

In [40]:

df

Out[40]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

In [41]:

df.groupby('name').mean()

Out[41]:

chinese math english
name
张三 18.000000 82.0 68.000000
李四 58.000000 61.0 69.000000
王五 58.666667 42.0 82.666667
赵六 94.000000 58.0 64.000000

In [43]:

x = df.groupby(['name', 'test'])[['chinese', 'math']].mean()
x

Out[43]:

image.png

重塑,轴向旋转

unstack()

In [44]:

x.unstack()

Out[44]:

image.png

分组、聚合、旋转:实现透视表和交叉表

In [48]:

# 分组聚合实现透视表
# 分组、mean聚合、选择、填充缺失值、转值类型
df.groupby(['name', 'test'])[['chinese', 'math']].mean().unstack().fillna(0).astype(np.int)

Out[48]:

image.png

In [54]:

# 分组聚合实现交叉表
# 分组,size聚合,选择,填充缺失值,值类型转换
df.groupby(['name', 'test'])[['chinese', 'math']].size().unstack().fillna(0).astype(np.int)
df.groupby(['name', 'test']).size().unstack().fillna(0).astype(np.int)

Out[54]:

test
name
张三 1 0 0
李四 1 0 1
王五 1 1 1
赵六 1 0 0

透视表方法:平均值

mean,len

# 示例:
tips.pivot_table(['tip_pct', 'size'], index=['time', 'day'], columns='smoker', margins=True, aggfunc=len, fill_value=0)

In [56]:

df.pivot_table(['chinese', 'math'], index='name', columns='test', fill_value=0)

Out[56]:

image.png

交叉表:个数

# 示例
pd.crosstab(tips.time, [tips.smoker, tips.day], margins=True)

In [58]:

pd.crosstab(df.name, df.test, margins=True)

Out[58]:

test All
name
张三 1 0 0 1
李四 1 0 1 2
王五 1 1 1 3
赵六 1 0 0 1
All 4 1 2 7

表格操作

索引修改

  • 将普通列转为行索引:.set_index()
  • 行索引转为普通列(删除行索引):reset_index()
  • 修改行列索引:.rename()

排序

  • 按值排序:.sort_values()
  • 按索引排序:.sort_index()

In [59]:

df

Out[59]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

In [62]:

y = df.set_index('name')  # 将1列数据设为行索引
y

df.set_index('name', append=True)  # 保留原索引,创建新索引

Out[62]:

chinese math english test
name
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

行索引还原为数据列

In [63]:

y

Out[63]:

chinese math english test
name
张三 18 82 68
李四 53 63 52
王五 67 41 90
李四 63 59 86
王五 39 46 60
王五 70 39 98
赵六 94 58 64

In [66]:

df.set_index('name').reset_index()  # 行索引还原为列数据
df.set_index('name').reset_index(drop=True)  # drop=True,删掉行索引列

Out[66]:

chinese math english test
0 18 82 68
1 53 63 52
2 67 41 90
3 63 59 86
4 39 46 60
5 70 39 98
6 94 58 64

修改行列索引

In [71]:

df3 = df.rename(index={0: 'aaa', 1: 'bbb'}, columns={'name': '姓名', 'chinese': '语文'})
df3

Out[71]:

姓名 语文 math english test
aaa 张三 18 82 68
bbb 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

In [72]:

df3.loc['aaa']

Out[72]:

姓名         张三
语文         18
math       82
english    68
test        一
Name: aaa, dtype: object

排序

  • 按索引排序,按值排序
  • 按行排序,按列排序
  • 升序,降序

按索引排序

In [76]:

df

df.sort_index()  # 默认:按行索引排序,升序
df.sort_index(ascending=False)  # 降序
df.sort_index(axis=1, ascending=False)  # 按列索引排序,降序

Out[76]:

test name math english chinese
0 张三 82 68 18
1 李四 63 52 53
2 王五 41 90 67
3 李四 59 86 63
4 王五 46 60 39
5 王五 39 98 70
6 赵六 58 64 94

按值排序

In [79]:

df.sort_values(by='math')  # 指定某列排序
df.sort_values(by='math', ascending=False)  # 降序

Out[79]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
3 李四 63 59 86
6 赵六 94 58 64
4 王五 39 46 60
2 王五 67 41 90
5 王五 70 39 98

Pandas绘图(结合Matplotlib)

柱状

In [80]:

df.plot.bar()

Out[80]:

<matplotlib.axes._subplots.AxesSubplot at 0x9009da0>
output_61_1.png

In [88]:

df.plot.bar(
    stacked=True,
    
    figsize=(18, 7),
    alpha=0.5,
)

# matplotlib和pandas结合操作
plt.title('图像标题', fontsize=24)
plt.xticks(df.index, ['一','二','三','四','五','六','七'])
plt.show()
output_62_0.png

自定义函数

.apply()

用在什么地方:

当你想反复执行一个数据操作时,首先考虑能否使用Pandas自带的方法(交叉表、透视表、分组聚合、其他表格操作)实现,如果不能实现,就自定义一个函数使用apply调用自定义函数

如果不方便使用自定义函数,那就使用for循环遍历

注意:先用一组数据中的一个手动实现一遍程序,再封装为函数,不容易出错

例:查询语文成绩不及格的同学信息

In [89]:

df

Out[89]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
2 王五 67 41 90
3 李四 63 59 86
4 王五 39 46 60
5 王五 70 39 98
6 赵六 94 58 64

使用Pandas原生方法实现

In [93]:

df['chinese'] < 60

Out[93]:

0     True
1     True
2    False
3    False
4     True
5    False
6    False
Name: chinese, dtype: bool

In [92]:

df[df['chinese'] < 60]

Out[92]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
4 王五 39 46 60

DataFrame自定义函数原理

In [110]:

# Series自定义函数原理

def aaa(x):
#     return x
    return type(x)

df['chinese'].apply(aaa)  # Series调用

Out[110]:

0    <class 'int'>
1    <class 'int'>
2    <class 'int'>
3    <class 'int'>
4    <class 'int'>
5    <class 'int'>
6    <class 'int'>
Name: chinese, dtype: object

In [120]:

# DataFrame自定义函数原理

def aaa(x):
    # DataFrame返回值
#     return x
#     return type(x)

#     return x[0]
    return(type(x[0]))

df.apply(aaa)  # DataFrame
df.apply(aaa, axis=0)  # 按行运算,同上
df.apply(aaa, axis=1)  # 按列运算

Out[120]:

0    <class 'str'>
1    <class 'str'>
2    <class 'str'>
3    <class 'str'>
4    <class 'str'>
5    <class 'str'>
6    <class 'str'>
dtype: object

使用自定义函数实现

In [116]:

# 方法1:Series实现

def bbb(x):
#     if x < 60:
#         return True
#     else:
#         return False

    # 三元表达式
    return True if x < 60 else False

df['chinese'].apply(bbb)
df[df['chinese'].apply(bbb)]

Out[116]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
4 王五 39 46 60

In [123]:

# 方法2:DataFrame实现

def ccc(x):
    if x['chinese'] < 60:
        return True
    else:
        return False

    # 三元表达式
    return True if x['chinese'] < 60 else False

df.apply(ccc, axis=1)  # 按列运算
df[df.apply(ccc, axis=1)]

Out[123]:

name chinese math english test
0 张三 18 82 68
1 李四 53 63 52
4 王五 39 46 60
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容