Pandas实战:分析三国志人物示例实现

简介
背景

Pandas 是 Python 的一个工具库,用于数据分析。由 AQR Capital Management 于 2008 年 4 月开发,2009 年开源,最初被作为金融数据分析工具而开发出来。Pandas 名称来源于 panel data(面板数据)和 Python data analysis(Python 数据分析)。适用于金融、统计等数据分析领域。

特点:两大数据结构

Series 和 DataFrame

(1)Series:一维数据(列+索引)

pandas.Series(['东汉', '马腾', '?', 212], index=['国家', '姓名', '出生年份', '逝世年份'])

C98B6731-09A6-4FAD-2334-63B5A3EA2F11.png

(2)DataFrame:二维数据(表格:多个列+行/列索引)

E0DEED00-143D-7A80-B22A-5F1BCC9E70AE.png

pandas.DataFrame([
    ['东汉', 300],
    ['魏国', 800],
    ['蜀国', 400],
    ['吴国', 600],
    ['西晋', 1000]
], columns=['国家', '国力'])

57A4D218-5FC8-95D5-67D9-3F4DF7F297B1.png

安装

如果你使用的是数据科学的 Python 发行版:Anaconda,可以使用 conda 安装

conda install pandas

如果是普通的 Python 环境,可以使用 pip 安装

pip install pandas
实战

我们先看看数据长啥样,数据存在 sanguo.csv 文档中

$ head sanguo.csv

A2D453A3-6A06-626D-6FB6-13124930CB5E.png

(1)导入模块

import pandas as pd

(2)读取 csv 数据

# 当前目录下的 sanguo.csv 文件,na_values 指定哪些值为空
df = pd.read_csv('./sanguo.csv', na_values=['na', '-', 'N/A', '?'])

1)查看数据

# 查看前 5 条
df.head(5)
# NaN 为空值

E91029F3-EAF7-A0D8-E896-C32CEAD0BD41.png

# 查看后 5 条
df.tail(5)

7B11810E-5C91-4D8D-B532-B3FA469B009D.png

2)查看数据概况

df.dtypes
# 查看数据类型

F3298BFC-E640-67D0-3B87-3070301021C0.png

df.info()
# 有 25 行,5 列
# 各列的名称(kindom、name、birth、die、character)、非空数目、数据类型

7075B623-BD6F-A124-4AB2-98DE8BF98774.png

df.describe()
# 查看数值型列统计值:总数、平均值、标准差、最小值、25%/50%/75% 分位数、最大值

B47B67A9-E4F4-6379-D780-5D8F2ADCB4BE.png

3)数据操作

设置列名

df.columns = ['国家', '姓名', '出生年份', '逝世年份', '角色']
df.head()

79BF08B9-D1D8-1283-6BAE-DC161D82477D.png

添加新列

# 计算年龄
df['年龄'] = df['逝世年份'] - df['出生年份']
df.head(10)

3D04BE20-8340-9C55-97C0-A20DE3D8222D.png

计算列平均值、中位数、众数、最/小值

功能 函数  
平均值 df['年龄'].mean() 50.57142857142857
中位数 df['年龄'].median() 53.0
众数 df['年龄'].mode() 72.0
最大值 df['年龄'].max() 72.0
最小值 df['年龄'].min() 12.0

列筛选

# 筛选年轮小于 50 的数据
df[df['年龄'] < 50]

46032935-AC16-573E-F9BB-55627887D5A5.png

# 筛选曹姓的数据
df[df['姓名'].str.startswith('曹')]

9B635616-9AE4-8016-1DC5-0E26CDF9FAAE.png

分组

df.groupby('国家')['姓名'].count()
# 类似于 SQL: SELECT 国家, COUNT(姓名) FROM x GROUP BY 国家

3A6EF015-A58D-E88D-3946-381C3951F271.png

apply 函数

df['状态'] = df['年龄'].apply(lambda x: '长寿' if isinstance(x, (int, float)) and x > 50 else '一般')
df.head()

0F16500E-16DC-5625-C04C-9C72F1920214.png

取数据:loc、iloc

     
df.loc[4] 取第 5 行数据(索引从 0 开始) 7DF6AB7A-8A6B-D6CD-C2A8-BD7E71B72815.png
df.loc[4:5] 取第 5~6 行数据 7743A143-2B81-68F7-38A4-20D2F7F1D4C9.png
df.loc[4, '姓名']

df.iloc[4, 1]

取第 5 行姓名列

或第 5 行第 2 列

7869D841-2D04-3379-B718-4EA108DFB9CB.png
df.loc[4, ['姓名', '年龄']]

df.iloc[4, [1, 5]]

取第 5 行姓名、年龄列

或第 5 行第 2 列、第 6 列

C0945D85-58F7-DD5D-FC3E-50348002E560.png
df.loc[4:5, ['姓名', '年龄']]

df.iloc[[4, 5], [1, 5]]

df.iloc[4:6, [1, 5]]

取第 5~6 行姓名、年龄列

或取第 5~6 行第 2 列、第 6 列

A00627CE-80D0-02FA-D183-F6E729F56923.png
df.iloc[4:9, 1:4] 取 5~10 列第 2~5 列 99171750-DE5F-9665-1602-0CAAB3558085.png

追加、合并数据

concat

# 创建列
newpeople = pd.Series(['东汉', '马腾', '?', 212, '?'], index=['国家', '姓名', '出生年份', '逝世年份', '年龄'])

# 将 Series 转为 DataFrame,并对 DataFrame 转置(列转行)
newpeople = newpeople.to_frame().T

# 追加行(axis=0),重置索引(ignore_index=True)
df2 = pd.concat([df, newpeople], axis=0, ignore_index=True)
df2.tail()

A2D22C39-B0B7-9A7E-2CB8-57E4FCDE7BBC.png

merge

# 创建表格
kindom_power = pd.DataFrame([
    ['东汉', 300],
    ['魏国', 800],
    ['蜀国', 400],
    ['吴国', 600],
    ['西晋', 1000]
], columns=['国家', '国力'])

# 按国家列进行两个表格(左 df,右 kindom_power)合并
df3 = pd.merge(left=df, right=kindom_power, on='国家')
df3.head(10)

53802088-6D08-7291-5FC9-82D86417CC28.png

4)导出数据

# 写入 sanguo_result.csv 中,不输出索引值
df.to_csv('sanguo_result.csv', index=False)

988270B3-8A3A-5EC6-3AE8-F9C26DDC5C5B.png

参考
  • https://pandas.pydata.org/
  • https://www.runoob.com/pandas/pandas-tutorial.html
  • https://github.com/xchenhao/code-notes/blob/master/data/sanguo.csv sanguo.csv 数据
收藏 (0)
评论列表
正在载入评论列表...
我是有底线的
为您推荐
    暂时没有数据