Pandas 安装
安装 pandas 需要基础环境是 Python,开始前我们假定你已经安装了 Python 和 Pip。
使用 pip 安装 pandas:
!pip install pandas
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: pandas in d:\anaconda3\lib\site-packages (1.2.4)
Requirement already satisfied: pytz>=2017.3 in d:\anaconda3\lib\site-packages (from pandas) (2021.1)
Requirement already satisfied: numpy>=1.16.5 in d:\anaconda3\lib\site-packages (from pandas) (1.21.2)
Requirement already satisfied: python-dateutil>=2.7.3 in d:\anaconda3\lib\site-packages (from pandas) (2.8.1)
Requirement already satisfied: six>=1.5 in d:\anaconda3\lib\site-packages (from python-dateutil>=2.7.3->pandas) (1.15.0)
1. 实例 - 查看 pandas 版本
import pandas
pandas.__version__ # 查看版本
'1.2.4'
导入 pandas 一般使用别名 pd
来代替:
import pandas as pd
2. 一个简单的 pandas 实例:
import pandas as pd
mydataset = {
'sites': ["Google", "Runoob", "Wiki"],
'number': [1, 2, 3]
}
myvar = pd.DataFrame(mydataset)
print(myvar)
sites number
0 Google 1
1 Runoob 2
2 Wiki 3
Pandas 数据结构 - Series
Pandas Series 类似表格中的一个列(column),类似于一维数组,可以保存任何数据类型。
Series 由索引(index)和列组成,函数如下:
pandas.Series( data, index, dtype, name, copy)
参数说明:
-
data
:一组数据(ndarray 类型)。 -
index
:数据索引标签,如果不指定,默认从 0 开始。 -
dtype
:数据类型,默认会自己判断。 -
name
:设置名称。 -
copy
:拷贝数据,默认为 False。
1. 创建一个简单的 Series 实例(通过列表创建):
import pandas as pd
a = [1, 2, 3]
myvar = pd.Series(a)
print(myvar)
0 1
1 2
2 3
dtype: int64
2. 索引说明
如果没有指定索引,索引值就从 0 开始,我们可以根据索引值读取数据:
print(myvar[1])
2
我们可以指定索引值,如下实例:
import pandas as pd
a = ["Google", "Runoob", "Wiki"]
myvar = pd.Series(a, index = ["x", "y", "z"])
print(myvar)
x Google
y Runoob
z Wiki
dtype: object
根据索引值读取数据:
print(myvar["y"])
Runoob
3. 通过字典创建
我们也可以使用 key/value 对象,类似字典来创建 Series (字典的 key 会变成索引值):
import pandas as pd
sites = {1: "Google", 2: "Runoob", 3: "Wiki"}
myvar = pd.Series(sites)
print(myvar)
1 Google
2 Runoob
3 Wiki
dtype: object
如果我们只需要字典中的一部分数据,只需要指定需要数据的索引即可,如下实例:
myvar = pd.Series(sites, index = [1, 2])
print(myvar)
1 Google
2 Runoob
dtype: object
4. 设置 Series 名称参数
myvar = pd.Series(sites, index = [1, 2], name="RUNOOB-Series-TEST" )
print(myvar)
1 Google
2 Runoob
Name: RUNOOB-Series-TEST, dtype: object
Pandas 数据结构 - DataFrame
DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kboqKrjR-1629103208563)(https://www.runoob.com/wp-content/uploads/2021/04/pandas-DataStructure.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mhBGOiSW-1629103208570)(https://www.runoob.com/wp-content/uploads/2021/04/df-dp.png)]
DataFrame 构造方法如下:
pandas.DataFrame( data, index, columns, dtype, copy)
参数说明:
-
data
:一组数据(ndarray、series, map, lists, dict 等类型)。 -
index
:索引值,或者可以称为行标签。 -
columns
:列标签,默认为 RangeIndex (0, 1, 2, …, n) 。 -
dtype
:数据类型。 -
copy
:拷贝数据,默认为 False。
Pandas DataFrame 是一个二维的数组结构,类似二维数组。
1. 实例 - 使用列表创建
import pandas as pd
data = [['Google',10],['Runoob',12],['Wiki',13]]
df = pd.DataFrame(data,columns=['Site','Age'],dtype=float)
print(df)
Site Age
0 Google 10.0
1 Runoob 12.0
2 Wiki 13.0
以下实例使用 ndarrays 创建,ndarray 的长度必须相同, 如果传递了 index,则索引的长度应等于数组的长度。如果没有传递索引,则默认情况下,索引将是range(n),其中n是数组长度。
ndarrays 可以参考:NumPy Ndarray 对象
2. 实例 - 使用 ndarrays 创建
import pandas as pd
data = {'Site':['Google', 'Runoob', 'Wiki'], 'Age':[10, 12, 13]}
df = pd.DataFrame(data)
print (df)
Site Age
0 Google 10
1 Runoob 12
2 Wiki 13
还可以使用字典(key/value),其中字典的 key 为列名:
3. 实例 - 使用字典创建
import pandas as pd
data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
df = pd.DataFrame(data)
print (df)
a b c
0 1 2 NaN
1 5 10 20.0
没有对应的部分数据为 NaN。
4. 数据索引
Pandas 可以使用 loc
属性返回指定行的数据,如果没有设置索引,第一行索引为 0,第二行索引为 1,以此类推:
import pandas as pd
data = {
"calories": [420, 380, 390],
"duration": [50, 40, 45]
}
# 数据载入到 DataFrame 对象
df = pd.DataFrame(data)
print(df)
calories duration
0 420 50
1 380 40
2 390 45
# 返回第一行
print(df.loc[0])
calories 420
duration 50
Name: 0, dtype: int64
# 返回第二行
print(df.loc[1])
calories 380
duration 40
Name: 1, dtype: int64
注意: 返回结果其实就是一个 Pandas Series 数据。
也可以返回多行数据,使用 [[ ... ]]
格式,...
为各行的索引,以逗号隔开:
# 返回第一行和第二行
print(df.loc[[0, 1]])
calories duration
0 420 50
1 380 40
注意: 返回结果其实就是一个 Pandas DataFrame 数据。
5. 指定索引值
我们可以指定索引值,如下实例:
df = pd.DataFrame(data, index = ["day1", "day2", "day3"])
print(df)
calories duration
day1 420 50
day2 380 40
day3 390 45
Pandas 可以使用 loc
属性返回指定索引对应到某一行:
# 指定索引
print(df.loc["day2"])
calories 380
duration 40
Name: day2, dtype: int64
Pandas CSV 文件
CSV(Comma-Separated Values,逗号分隔值,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。
CSV 是一种通用的、相对简单的文件格式,被用户、商业和科学广泛应用。
1. 导入CSV文件
import pandas as pd
#从文件导入
df = pd.read_csv('./File/nba.csv')
#从url导入
df = pd.read_csv('https://static.runoob.com/download/nba.csv')
print(df.to_string())
to_string()
用于返回 DataFrame 类型的数据,如果不使用该函数,则输出结果为数据的前面 5 行和末尾 5 行,中间部分以 ...
代替。
print(df)
Name Team Number Position Age Height Weight \
0 Avery Bradley Boston Celtics 0.0 PG 25.0 6-2 180.0
1 Jae Crowder Boston Celtics 99.0 SF 25.0 6-6 235.0
2 John Holland Boston Celtics 30.0 SG 27.0 6-5 205.0
3 R.J. Hunter Boston Celtics 28.0 SG 22.0 6-5 185.0
4 Jonas Jerebko Boston Celtics 8.0 PF 29.0 6-10 231.0
.. ... ... ... ... ... ... ...
453 Shelvin Mack Utah Jazz 8.0 PG 26.0 6-3 203.0
454 Raul Neto Utah Jazz 25.0 PG 24.0 6-1 179.0
455 Tibor Pleiss Utah Jazz 21.0 C 26.0 7-3 256.0
456 Jeff Withey Utah Jazz 24.0 C 26.0 7-0 231.0
457 NaN NaN NaN NaN NaN NaN NaN
College Salary
0 Texas 7730337.0
1 Marquette 6796117.0
2 Boston University NaN
3 Georgia State 1148640.0
4 NaN 5000000.0
.. ... ...
453 Butler 2433333.0
454 NaN 900000.0
455 NaN 2900000.0
456 Kansas 947276.0
457 NaN NaN
[458 rows x 9 columns]
2. 导出为csv文件
我们也可以使用 to_csv()
方法将 DataFrame 存储为 csv 文件:
import pandas as pd
# 三个字段 name, site, age
nme = ["Google", "Runoob", "Taobao", "Wiki"]
st = ["www.google.com", "www.runoob.com", "www.taobao.com", "www.wikipedia.org"]
ag = [90, 40, 80, 98]
# 字典
dict = {'name': nme, 'site': st, 'age': ag}
df = pd.DataFrame(dict)
# 保存 dataframe
df.to_csv('./File/site.csv')
执行成功后,我们打开 site.csv 文件,显示结果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dBb8ukVy-1629103208572)(https://www.runoob.com/wp-content/uploads/2021/05/9758194A-0D8E-4C53-95A0-157C690614E6.jpg)]
3. 数据处理 - head()
head( n )
方法用于读取前面的 n 行,如果不填参数 n ,默认返回 5 行。
import pandas as pd
df = pd.read_csv('./File/nba.csv')
print(df.head())
Name Team Number Position Age Height Weight \
0 Avery Bradley Boston Celtics 0.0 PG 25.0 6-2 180.0
1 Jae Crowder Boston Celtics 99.0 SF 25.0 6-6 235.0
2 John Holland Boston Celtics 30.0 SG 27.0 6-5 205.0
3 R.J. Hunter Boston Celtics 28.0 SG 22.0 6-5 185.0
4 Jonas Jerebko Boston Celtics 8.0 PF 29.0 6-10 231.0
College Salary
0 Texas 7730337.0
1 Marquette 6796117.0
2 Boston University NaN
3 Georgia State 1148640.0
4 NaN 5000000.0
4. 数据处理 - tail()
tail( n )
方法用于读取尾部的 n 行,如果不填参数 n ,默认返回 5 行,空行各个字段的值返回 NaN。
print(df.tail())
Name Team Number Position Age Height Weight College \
453 Shelvin Mack Utah Jazz 8.0 PG 26.0 6-3 203.0 Butler
454 Raul Neto Utah Jazz 25.0 PG 24.0 6-1 179.0 NaN
455 Tibor Pleiss Utah Jazz 21.0 C 26.0 7-3 256.0 NaN
456 Jeff Withey Utah Jazz 24.0 C 26.0 7-0 231.0 Kansas
457 NaN NaN NaN NaN NaN NaN NaN NaN
Salary
453 2433333.0
454 900000.0
455 2900000.0
456 947276.0
457 NaN
5. 数据处理 - info()
info()
方法返回表格的一些基本信息:
print(df.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 458 entries, 0 to 457
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Name 457 non-null object
1 Team 457 non-null object
2 Number 457 non-null float64
3 Position 457 non-null object
4 Age 457 non-null float64
5 Height 457 non-null object
6 Weight 457 non-null float64
7 College 373 non-null object
8 Salary 446 non-null float64
dtypes: float64(4), object(5)
memory usage: 32.3+ KB
None
Pandas JSON
JSON(JavaScript Object Notation,JavaScript 对象表示法),是存储和交换文本信息的语法,类似 XML。
JSON 比 XML 更小、更快,更易解析,更多 JSON 内容可以参考 JSON 教程。
1. 将 JSON 字符串转化为 DataFrame
import pandas as pd
data =[
{
"id": "A001",
"name": "菜鸟教程",
"url": "www.runoob.com",
"likes": 61
},
{
"id": "A002",
"name": "Google",
"url": "www.google.com",
"likes": 124
},
{
"id": "A003",
"name": "淘宝",
"url": "www.taobao.com",
"likes": 45
}
]
df = pd.DataFrame(data)
print(df)
id name url likes
0 A001 菜鸟教程 www.runoob.com 61
1 A002 Google www.google.com 124
2 A003 淘宝 www.taobao.com 45
2. 导入JSON
其中 to_string()
用于返回 DataFrame 类型的数据。
import pandas as pd
#从文件导入
df = pd.read_json('./File/sites.json')
#从url导入
df = pd.read_json('https://static.runoob.com/download/sites.json')
print(df.to_string())
id name url likes
0 A001 菜鸟教程 www.runoob.com 61
1 A002 Google www.google.com 124
2 A003 淘宝 www.taobao.com 45
3. 读取内嵌的 JSON 数据
假设有一组内嵌的 JSON 数据文件 nested_list.json
:
{
"school_name": "ABC primary school",
"class": "Year 1",
"students": [
{
"id": "A001",
"name": "Tom",
"math": 60,
"physics": 66,
"chemistry": 61
},
{
"id": "A002",
"name": "James",
"math": 89,
"physics": 76,
"chemistry": 51
},
{
"id": "A003",
"name": "Jenny",
"math": 79,
"physics": 90,
"chemistry": 78
}]
}
使用以下代码格式化完整内容:
import pandas as pd
df = pd.read_json('./File/nested_list.json')
print(df)
school_name class \
0 ABC primary school Year 1
1 ABC primary school Year 1
2 ABC primary school Year 1
students
0 {'id': 'A001', 'name': 'Tom', 'math': 60, 'phy...
1 {'id': 'A002', 'name': 'James', 'math': 89, 'p...
2 {'id': 'A003', 'name': 'Jenny', 'math': 79, 'p...
可以看出输出结果并不理想,这时我们就需要使用到 json_normalize()
方法将内嵌的数据完整的解析出来:
import pandas as pd
import json
# 使用 Python JSON 模块载入数据
with open('./File/nested_list.json','r') as f:
data = json.loads(f.read())
# 展平数据
df_nested_list = pd.json_normalize(data, record_path =['students'])
print(df_nested_list)
id name math physics chemistry
0 A001 Tom 60 66 61
1 A002 James 89 76 51
2 A003 Jenny 79 90 78
# 展平数据
df_nested_list = pd.json_normalize(
data,
record_path =['students'],
meta=['school_name', 'class']
)
print(df_nested_list)
id name math physics chemistry school_name class
0 A001 Tom 60 66 61 ABC primary school Year 1
1 A002 James 89 76 51 ABC primary school Year 1
2 A003 Jenny 79 90 78 ABC primary school Year 1
json_normalize()
使用了参数 record_path
并设置为 ['students']
用于展开内嵌的 JSON 数据 students
。
显示结果还没有包含 school_name
和 class
元素,如果需要展示出来可以使用 meta
参数来显示这些元数据
接下来,让我们尝试读取更复杂的 JSON 数据,该数据嵌套了列表和字典,数据文件 nested_mix.json 如下:
{
"school_name": "local primary school",
"class": "Year 1",
"info": {
"president": "John Kasich",
"address": "ABC road, London, UK",
"contacts": {
"email": "admin@e.com",
"tel": "123456789"
}
},
"students": [
{
"id": "A001",
"name": "Tom",
"math": 60,
"physics": 66,
"chemistry": 61
},
{
"id": "A002",
"name": "James",
"math": 89,
"physics": 76,
"chemistry": 51
},
{
"id": "A003",
"name": "Jenny",
"math": 79,
"physics": 90,
"chemistry": 78
}]
}
import pandas as pd
import json
# 使用 Python JSON 模块载入数据
with open('./File/nested_mix.json','r') as f:
data = json.loads(f.read())
df = pd.json_normalize(
data,
record_path =['students'],
meta=[
'class',
['info', 'president'],
['info', 'contacts', 'tel']
]
)
print(df)
id name math physics chemistry class info.president \
0 A001 Tom 60 66 61 Year 1 John Kasich
1 A002 James 89 76 51 Year 1 John Kasich
2 A003 Jenny 79 90 78 Year 1 John Kasich
info.contacts.tel
0 123456789
1 123456789
2 123456789
4. 读取内嵌数据中的一组数据
以下是实例文件 nested_deep.json,我们只读取内嵌中的 math 字段:
{
"school_name": "local primary school",
"class": "Year 1",
"students": [
{
"id": "A001",
"name": "Tom",
"grade": {
"math": 60,
"physics": 66,
"chemistry": 61
}
},
{
"id": "A002",
"name": "James",
"grade": {
"math": 89,
"physics": 76,
"chemistry": 51
}
},
{
"id": "A003",
"name": "Jenny",
"grade": {
"math": 79,
"physics": 90,
"chemistry": 78
}
}]
}
这里我们需要使用到 glom
模块来处理数据套嵌,glom
模块允许我们使用 .
来访问内嵌对象的属性。
第一次使用我们需要安装 glom
:
!pip3 install glom
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting glom
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/5a/e2/977d77f6e0c34902f05a0754beb5950ea70c3c3c935d571fccac9540b57a/glom-20.11.0-py2.py3-none-any.whl (97 kB)
Collecting boltons>=19.3.0
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/f7/a7/1a31561d10a089fcb46fe286766dd4e053a12f6e23b4fd1c26478aff2475/boltons-21.0.0-py2.py3-none-any.whl (193 kB)
Collecting face>=20.1.0
Downloading https://pypi.tuna.tsinghua.edu.cn/packages/ae/ab/2b18c4815f3db1e04bce325271fefda55d0893738ea84e3a655218944b03/face-20.1.1.tar.gz (46 kB)
Requirement already satisfied: attrs in d:\anaconda3\lib\site-packages (from glom) (20.3.0)
Building wheels for collected packages: face
Building wheel for face (setup.py): started
Building wheel for face (setup.py): finished with status 'done'
Created wheel for face: filename=face-20.1.1-py3-none-any.whl size=51078 sha256=1547f9fd13aea806ec4b29d006a5527a22ef2f5814da457d8d28be3b6c1441e0
Stored in directory: c:\users\dell\appdata\local\pip\cache\wheels\38\1e\e8\a4032cdb26900d12a09e565200404c1ceb4756fab5ae346f52
Successfully built face
Installing collected packages: boltons, face, glom
Successfully installed boltons-21.0.0 face-20.1.1 glom-20.11.0
import pandas as pd
from glom import glom
df = pd.read_json('./File/nested_deep.json')
print(df)
school_name class \
0 local primary school Year 1
1 local primary school Year 1
2 local primary school Year 1
students
0 {'id': 'A001', 'name': 'Tom', 'grade': {'math'...
1 {'id': 'A002', 'name': 'James', 'grade': {'mat...
2 {'id': 'A003', 'name': 'Jenny', 'grade': {'mat...
dataframe.apply(function, axis)
对一行或一列做出一些操作
-
axis = 1
遍历行(默认) -
axis = 0
遍历列
# 第0行
print(df['students'][0])
df['students'][0]
{'id': 'A001', 'name': 'Tom', 'grade': {'math': 60, 'physics': 66, 'chemistry': 61}}
{'id': 'A001',
'name': 'Tom',
'grade': {'math': 60, 'physics': 66, 'chemistry': 61}}
# 遍历每一行并打印
df['students'].apply(print)
#每一行都打印了出来,但每次打印返回值均为0,因此三行均为None
{'id': 'A001', 'name': 'Tom', 'grade': {'math': 60, 'physics': 66, 'chemistry': 61}}
{'id': 'A002', 'name': 'James', 'grade': {'math': 89, 'physics': 76, 'chemistry': 51}}
{'id': 'A003', 'name': 'Jenny', 'grade': {'math': 79, 'physics': 90, 'chemistry': 78}}
0 None
1 None
2 None
Name: students, dtype: object
# 读取第0行 math 字段
glom(df['students'][0], 'grade.math')
60
# 读取所有三行 math 字段 并组合为新的 Series
data = df['students'].apply(