大家好,我是Mr数据杨。今天我将带领各位走进Python的奇妙世界,就像步入三国演义那样热闹且复杂的战争年代。这里,数据就像那些智勇双全的武将和策士,我们要学习如何访问和修改它们,就如同诸葛亮那样掌控战局。
先来理解一下如何使用访问器获取和设置数据。这就好比郭嘉在典韦死后得知曹操对他的感激和痛惜的心情,然后再妥善安排后续事务。在Python中也能通过访问器获取数据的信息,再对其进行修改。
接下来将学习DataFrame的列操作,包括选取列、列间数据运算和过滤列。就像周瑜用火攻击策略可以选取数据,进行运算和过滤,从而达到想要的结果。
再来是行数据的插入和删除,这好比战场上将士的阵亡和新兵的加入。还会学习如何在DataFrame中插入和删除列数据,这就如同在三国演义中,新的谋士如司马懿的加入和老将如张辽的离去。
最后还将探讨列数据的赋值和分配。当刘备得到荆州,却又需要交出荆州时,他就在进行数据赋值和分配,Python也可以这样操作数据。
今天的教程就像一场三国演义般的大战,让我们用智慧和勇气一同开启Python的学习之旅!
文章目录
- Pandas 数据访问
- 预览数据
- 使用访问器获取数据
- 使用访问器设置数据
- 数据类型重新定义
- Pandas 检查数据
- 显示数据类型
- 显示基础统计
- 探索数据集
- Pandas 清理数据
- 缺失值
- 无效值
- 不一致的值
- DataFrame 列操作
- 列的条件选取
- 列间的数据运算
- 行数据插入和删除
- 列数据插入和删除
- 列数据赋值
- Pandas 分组和聚合
- Pandas 可视化
Pandas 数据访问
预览数据
在这个部分中将学习如何直接从Excel文件中读取数据,并进行一些相关的操作。
查看的数据基本信息。
import pandas as pd
# 读取数据
df = pd.read_excel("Romance of the Three Kingdoms 13/人物详情数据.xlsx")
# 数据类型
type(df)
<class 'pandas.core.frame.DataFrame'>
# 行数
len(df)
857
# 行、列数
df.shape
(857, 45)
数据的预览。
# 查看前5行数据
df.head()
可以看到一列省略号 (…) 表示缺失的数据。可以进行设置为滚动条显示。
pd.set_option("display.max.columns", 2)
# 显示最后5行数据
df.tail()
使用访问器获取数据
除了使用 .loc[]
访问器通过索引获取行或列的数据之外,Pandas还提供了 .iloc[]
访问器,它通过整数索引来检索行或列。
示例代码:
df.loc[10]
输出结果:
名前 阿会喃
字 -
读み -
性别 男
生年 190
登场 217
没年 225
...
酒\n興味 あり
物欲 强欲
Name: 10, dtype: object
df.iloc[0]
输出结果:
名前 阿会喃
字 -
读み -
性别 男
生年 190
登场 217
没年 225
...
酒\n興味 あり
物欲 强欲
Name: 10, dtype: object
.loc[]
和 .iloc[]
支持切片和类似NumPy的索引操作。
示例代码:
df.loc[:, '名前']
输出结果:
10 阿会喃
11 韋昭
12 伊籍
13 尹賞
14 尹大目
Name: 名前, dtype: object
df.iloc[:, 1]
输出结果:
10 阿会喃
11 韋昭
12 伊籍
13 尹賞
14 尹大目
Name: 名前, dtype: object
可以使用切片、列表或数组来获取多行或多列的数据。
示例代码:
df.loc[11:15, ['名前', '字']]
输出结果:
名前 字
11 韋昭 弘嗣
12 伊籍 機伯
13 尹賞 -
14 尹大目 -
df.iloc[1:6, [0, 1]]
输出结果:
名前 字
11 韋昭 弘嗣
12 伊籍 機伯
13 尹賞 -
14 尹大目 -
.iloc[]
可以使用与切片元组、列表和NumPy数组相同的方式跳过行和列。
示例代码:
df.iloc[1:6:2, 0]
输出结果:
11 韋昭
13 尹賞
Name: 名前, dtype: object
还可以使用Python内置的 slice()
类、numpy.s_[]
或者 pd.IndexSlice[]
。
示例代码:
df
.iloc[slice(1, 6, 2), 0]
输出结果:
11 韋昭
13 尹賞
Name: 名前, dtype: object
df.iloc[np.s_[1:6:2], 0]
输出结果:
11 韋昭
13 尹賞
Name: 名前, dtype: object
df.iloc[pd.IndexSlice[1:6:2], 0]
输出结果:
11 韋昭
13 尹賞
Name: 名前, dtype: object
使用 .loc[]
和 .iloc[]
获取特定的数据值。但是当只需要单个值时,建议使用专门的访问器 .at[]
和 .iat[]
。
示例代码:
df.at[12, '名前']
输出结果:
'伊籍'
df.iat[2, 0]
输出结果:
'伊籍'
使用访问器设置数据
可以使用访问器来修改数据,可以传递Python序列、NumPy数组或单个值来修改数据。
示例代码:
df.loc[:13, '生年'] = [40, 50, 60, 70]
df.loc[14:, '生年'] = 0
df['生年']
输出结果:
10 40
11 50
12 60
13 70
14 0
Name: 生年, dtype: int64
可以使用负索引 .iloc[]
来访问或修改数据。
示例代码:
df.iloc[:, -10] = np.array([88.0, 79.0, 81.0, 80.0, 68.0, 61.0, 84.0])
df['生年']
输出结果:
10 88.0
11 79.0
12 81.0
13 80.0
14 68.0
Name: 生年, dtype: float64
数据类型重新定义
这里重新定义的数据类型是根据列全部重新定义。重新定义 object 直接赋值修改数据类型。
df["寿命"] = df["寿命"].astype('object')
Pandas 检查数据
在这个部分将学习如何检查数据的类型以及进行基本的统计操作。
显示数据类型
可以看到数据类型包括int64和object。Pandas使用NumPy库来处理这些数据类型。数据类型 int64 和 object。
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 857 entries, 0 to 856
Data columns (total 45 columns):
名前 857 non-null object
字 857 non-null object
読み 857 non-null object
性別 857 non-null object
生年 857 non-null int64
登場 857 non-null int64
没年 857 non-null int64
寿命 857 non-null int64
死因 857 non-null object
父親 857 non-null object
母親 857 non-null object
相性 857 non-null object
列伝 857 non-null object
商業 857 non-null int64
農業 857 non-null int64
文化 857 non-null int64
訓練 857 non-null int64
巡察 857 non-null int64
説破 857 non-null int64
交渉 857 non-null int64
弁舌 857 non-null int64
人徳 857 non-null int64
威風 857 non-null int64
神速 857 non-null int64
奮戦 857 non-null int64
連戦 857 non-null int64
攻城 857 non-null int64
兵器 857 non-null int64
堅守 857 non-null int64
水連 857 non-null int64
一騎 857 non-null int64
豪傑 857 non-null int64
鬼謀 857 non-null int64
音声 857 non-null object
武器 857 non-null object
性格 857 non-null object
義理 857 non-null object
勇愛 857 non-null object
才愛 857 non-null object
分類 857 non-null object
武具
興味 857 non-null object
書物
興味 857 non-null object
宝物
興味 857 non-null object
酒
興味 857 non-null object
物欲 857 non-null object
dtypes: int64(24), object(21)
memory usage: 301.4+ KB
显示基础统计
该方法可以显示所有数字列的一些基本描述性统计信息。
df.describe()
使用 include 参数可以查看其他数据类型。不会计算 object 列的平均值或标准差,只显示一些描述性统计信息。
import numpy as np
df.describe(include=object)
探索数据集
探索性数据分析可以回答关于数据集的一些问题。
例如特定值在列中出现的频率。
df["性格"].value_counts()
冷静 290
豪胆 223
小心 178
猪突 165
? 1
Name: 性格, dtype: int64
df["分類"].value_counts()
武官 520
文官 336
? 1
Name: 分類, dtype: int64
Pandas 清理数据
在这个部分将学习如何清理数据中的缺失值、无效值和不一致的值。
缺失值
处理包含缺失值的记录的最简单方法是忽略或者删除。
df_drop = df.dropna()
缺失值也可以进行填充。
df_drop = df.copy()
df_drop ["字"].fillna(
value="-",
inplace=True
)
无效值
无效值可能比缺失值更难处理,也会为后续的数据分析操作造成各种不可未知的麻烦。这个需要根据自己对业务的理解剔除相关不合理的或者异常的数据。
不一致的值
可以定义一些互斥的查询条件,并验证这些条件不会同时出现。
判断出生年小于死亡年。
df[(df["没年"] > df["生年"]).empty
False
幸运的是这两个查询都返回一个空的DataFrame证明不存在不一致的数据。
DataFrame 列操作
列的条件选取
可以根据索引访问庞大数据集的子集,意味着可以根据索引来查询数据。
筛选200年后出生的人物。
born_date = df[df["生年"] > 200]
born_date.shape
(189, 45)
选定姓名中字为 - 的人物。
not_null_data = df[df["字"]!="-"]
not_null_data.shape
(381, 45)
选择姓为曹的人物。
people = df[df["名前"].str.startswith("曹")]
people.shape
(25, 45)
多条件搜索使用 & 符号。
df[
(df["名前"].str.startswith("曹")) &
(df["生年"] > 200) &
(df["分類"] == "文官")
]
列间的数据运算
创建原 df 的副本DataFrame 使用。
df_ = df.copy()
df_.shape
(857, 45)
自定义列间减法求寿命。
df["life"] = df["没年"] - df["生年"]
df["life"]
0 35
1 69
2 64
3 66
4 59
..
852 99
853 98
854 98
855 98
856 98
Name: life, Length: 857, dtype: int64
df["difference"].max()
68
列名可以重新自定义。
renamed_df = df.rename(
columns={"生年": "born", "没年": "death"}
)
也可以删除不需要的行或者列。
renamed_df.shape
(857, 46)
del_columns = ["寿命"]
# 这里需要指定 axis = 1 为列,axis = 0 为行
renamed_df.drop(del_columns , inplace=True, axis=1)
df.shape
(857, 45)
行数据插入和删除
创建要插入的新数据。
new = pd.Series(data=['Mr数据杨', 'xxx', "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"], index=df.columns)
new
输出结果:
名前 Mr数据杨
字 xxx
读み -
性别 -
生年 -
登场 -
没年 -
...
酒\n興味 -
物欲 -
dtype: object
使用 df.append()
将新数据加入DataFrame。
df = df.append(pd.DataFrame(new).T)
df
输出结果:
使用 df.drop()
删除新数据。
df = df.drop(labels=[17])
df
输出结果:
列数据插入和删除
可以直接赋值来定义新列的名称和数据。
示例代码:
df['temp_data'] = np.array([71.0, 95.0, 88.0, 79.0, 91.0])
df
输出结果:
可以将新列的所有值设置为0。
示例代码:
df['temp_data'] = 0.0
df
输出结果:
使用 .insert()
在指定位置插入列数据。
示例代码:
df.insert(loc=4, column='new_temp_data', value=np.array([86.0, 81.0, 78.0, 88.0, 74.0, 70.0, 81.0]))
df
输出结果:
使用 del
关键字删除一列或多列。
示例代码:
del df['new_temp_data']
df
输出结果:
使用 df.drop()
删除列。
示例代码:
df = df.drop(labels='age', axis=1)
df
输出结果:
列数据赋值
赋值标量自动在列里广播填充。
df['名前'] = 'xxxxx'
df
Pandas 分组和聚合
Pandas 库提供了分组和聚合函数进行各种数据的统计操作。
Series 有 20 多种不同的方法来计算描述性统计量。
A_.sum()
6
A_.min()
1
DataFrame 可以有多个列可以进行聚合分组操作。
根据 分類
聚合,求和寿命
列数据。
df.groupby("分類", sort=False)["寿命"].mean()
分類
武官 51.646154
文官 58.220238
? 104.000000
Name: 寿命, dtype: float64
Pandas 可视化
Series 和 DataFrame对象都有一个 .plot()
方法绘制可视化图。
"""
# 可选的图标模式有
- 'line' : 折线图
- 'bar' : 柱状图
- 'hist' : 直方图
- 'box' : 箱线图
.....
"""
data = df["性格"].value_counts()
data.plot('bar')