Pandas 是一个开源的 Python 数据分析库, 由 Wes McKinney 在 2008 年创建, 而且在接下来的几年中, 它迅速成为 Python 数据分析社区中最受欢迎和最有影响力的工具之一. Pandas 的名字来源于 Panel Data 和 Python Data Analysis.
Pandas 是一个开源的 Python 数据分析库, 它提供了大量功能, 能够帮助我们轻松的处理结构化数据. 在数据清洗, 转换, 分析中 Pandas 都是我们的得力助手.
对于我们开发者来说, Pandas 提供了一个强大的, 易于使用的数据结构和数据分析. Pandas 是数据清洗, 转换, 分析和可视化的首选.
列举一点 Pandas 的特点:
Pandas 的主要应用场景:
底层实现:
在 cmd 中输入:
pip install pandas
在 conda 中安装:
conda install pandas
查看是否安装成功:
import pandas as pd
Pandas 有两个核心的数据结构. “Series” 和 “DataFrame”. 我们先来讲 Series.
Series 是一个一维的标签化数组, Series 它可以容纳任何数据类型 (整型, 字符串, 浮点数, Python 对象等). Series 与普通的 Python 列表相似, 但是具有更多的功能和灵活性.
格式:
pd.Series(data, index=None, dtype=None, name=None, copy=None, fastpath=False)
参数:
例子:
import pandas as pd # 创建 Series 数组 list1 = [1, 2, 3] # 创建列表 series1 = pd.Series(list1) # 通过 list 创建 Series 数组 print(series1) # 调试输出 import pandas as pd # 创建 Series 数组, 带 Index student_name = ["张三", "李四", "我是小白呀"] # 创建学生名字列表, 用于索引学生id student_id = [1, 2, 3] # 创建学生 id 列表 series2 = pd.Series(student_id, index=student_name) # 创建 Series 数组 print(series2) # 调试输出 # 通过字典创建 Series 数组 dict1 = {'a':1,'b':2, 'c':3} # 创建字典 series3 = pd.Series(dict1) # 通过字典创建 Series 数组 print(series3) # 调试输出
输出结果:
0 1 1 2 2 3 dtype: int64 张三 1 李四 2 我是小白呀 3 dtype: int64 a 1 b 2 c 3 dtype: int64
Series 数组中, 我们可以通过索引来实现数据检索.
例子:
import pandas as pd # 创建 Series 数组, 带 Index student_name = ["张三", "李四", "我是小白呀"] # 创建学生名字列表, 用于索引学生id student_id = [1, 2, 3] # 创建学生 id 列表 series1 = pd.Series(student_id, index=student_name) # 创建 Series 数组 print(series1) # 调试输出 # 数据检索 zhangsan_id = series1["张三"] # 通过索引提取张三对应的 id lisi_id = series1["李四"] # 通过索引提取李四对应的 id iamarookie_id = series1["我是小白呀"] # 通过索引提取小白对应的 id print("张三的 id:", zhangsan_id) print("李四的 id:", lisi_id) print("张三的 id:", iamarookie_id) # 多重检索 ids = series1[["张三", "李四"]] # 通过索引提取张三和李四的 id print("张三 & 李四的 id: \n{}".format(ids)) # 调试输出
输出结果:
张三 1 李四 2 我是小白呀 3 dtype: int64 张三的 id: 1 李四的 id: 2 张三的 id: 3 张三 & 李四的 id: 张三 1 李四 2 dtype: int64
Series 数组中, 可以用过索引来修改 Series 中的数据.
例子:
import pandas as pd # 创建 Series 数组, 带 Index student_name = ["张三", "李四", "我是小白呀"] # 创建学生名字列表, 用于索引学生id student_id = [1, 2, 3] # 创建学生 id 列表 series1 = pd.Series(student_id, index=student_name) # 创建 Series 数组 print(series1) # 调试输出 # 数据修改 series1["张三"] = 123 # 将 Series 数组中, 索引张三对应的 id 修改为 123 print(series1) # 调试输出
输出结果:
张三 1 李四 2 我是小白呀 3 dtype: int64 张三 123 李四 2 我是小白呀 3 dtype: int64
Series 数组可以用过布尔索引来实现数据过滤.
例子:
import pandas as pd # 创建关于学生成绩的 Series 数组 student_name = ["张三", "李四", "我是小白呀"] # 创建学生名字列表, 用于索引学生成绩 student_grade = [88, 90, 55] # 创建学生成绩列表 series1 = pd.Series(student_grade, index=student_name) # 创建 Series 数组 print(series1) # 调试输出 # 数据修改 result = series1[series1 < 60] print("成绩不及格的同学: \n{}".format(result)) # 调试输出
输出结果:
张三 88 李四 90 我是小白呀 55 dtype: int64 成绩不及格的同学: 我是小白呀 55 dtype: int64
import pandas as pd # 创建关于学生成绩的 Series 数组 student_name = ["张三", "李四", "我是小白呀"] # 创建学生名字列表, 用于索引学生成绩 student_grade = [88, 90, 55] # 创建学生成绩列表 series1 = pd.Series(student_grade, index=student_name) # 创建 Series 数组 print("加分前: \n{}".format(series1)) # 调试输出 # Series 数组运算 series1 = series1 + 5 # 鉴于小白同学不及格, 老师觉得给大家都加 5 分 print("加分后: \n{}".format(series1)) # 调试输出
输出结果:
加分前: 张三 88 李四 90 我是小白呀 55 dtype: int64 加分后: 张三 93 李四 95 我是小白呀 60 dtype: int64
Pandas 中的 Series 提供了一种灵活且强大的方式来处理数据. 无论是数据分析, 数据清洗还是数据操作, Series 都是一个非常有用的工具.
DataFrame 是一个二维的标签化数据结构, 类似于一个 Excel 表格. DataFrame 中的值都是相同长度的 Series, DataFrame 是 Pandas 最常用和强大的数据结构.
通过使用pd.DataFrame函数我们可以创建 DataFrame 数组, DataFrame 可以由多种数据穿点, 如字典, 列表, 或外部文件.
格式:
pd.DataFrame(data=None, index=None, columns=None, dtype=None, copy=None)
参数:
例子:
import pandas as pd # 创建 DataFrame 数组 data = {"名字":["张三", "李四", "我是小白呀"], "年龄":[25, 32, 18]} # 创建字典 df = pd.DataFrame(data) # 由字典创建 DataFrame 数组 print(df) # 调试输出
输出结果:
名字 年龄 0 张三 25 1 李四 32 2 我是小白呀 18
在 Pandas 中, 索引是一个非常强大的工具, 可以帮我我们更有效的访问, 查询和操作数据. 在了解数据结构后, 我们需要理解如何利用索引进行数组操作.
通过列名, 我们可以检索 DataFrame 中的数据.
数据:
名字 年龄 第一行 张三 25 第二行 李四 32 第三行 我是小白呀 18
例子:
import pandas as pd # 创建 DataFrame 数组 data = {"名字":["张三", "李四", "我是小白呀"], "年龄":[25, 32, 18]} # 创建字典 df = pd.DataFrame(data, index=["第一行", "第二行", "第三行"]) # 由字典创建 DataFrame 数组 print(df) # 调试输出 # 检索名字列 name = df["名字"] # 提取名字列 print("提取名字列: \n{}".format(name)) # 调试输出 # 通过 iloc 实现切片 name = df.iloc[:,0] # 提取名字列 (所有行, 第一列) print("提取名字列: \n{}".format(name)) # 调试输出 # 通过 loc 实现切片 name = df.loc[:,"名字"] # 提取名字列 print("提取名字列: \n{}".format(name)) # 调试输出
输出结果:
名字 年龄 第一行 张三 25 第二行 李四 32 第三行 我是小白呀 18 提取名字列: 第一行 张三 第二行 李四 第三行 我是小白呀 Name: 名字, dtype: object 提取名字列: 第一行 张三 第二行 李四 第三行 我是小白呀 Name: 名字, dtype: object 提取名字列: 第一行 张三 第二行 李四 第三行 我是小白呀 Name: 名字, dtype: object
例子:
import pandas as pd # 创建 DataFrame 数组 data = {"名字":["张三", "李四", "我是小白呀"], "年龄":[25, 32, 18]} # 创建字典 df = pd.DataFrame(data, index=["第一行", "第二行", "第三行"]) # 由字典创建 DataFrame 数组 print(df) # 调试输出 # 检索第一行 row0 = df.iloc[0] # 提取第一行 print("提第一行: \n{}".format(row0)) # 调试输出 # 检索第一行 row0 = df.loc["第一行"] # 提取第一行 print("提第一行: \n{}".format(row0)) # 调试输出
输出结果:
名字 年龄 第一行 张三 25 第二行 李四 32 第三行 我是小白呀 18 提第一行: 名字 张三 年龄 25 Name: 第一行, dtype: object 提第一行: 名字 张三 年龄 25 Name: 第一行, dtype: object
在 Pandas 中, loc, iloc, ix都是用于选择数据的方法.
三者区别:
例子:
import pandas as pd # 创建 DataFrame 数组 data = {"名字":["张三", "李四", "我是小白呀"], "年龄":[25, 32, 18]} # 创建字典 df = pd.DataFrame(data) # 由字典创建 DataFrame 数组 print(df) # 调试输出 # 检索名字列 name = df["名字"] # 提取名字列 print("提取名字列: \n{}".format(name)) # 调试输出
输出结果:
名字 年龄 0 张三 25 1 李四 32 2 我是小白呀 18 提取名字列: 0 张三 1 李四 2 我是小白呀 Name: 名字, dtype: object
格式:
pd.DataFrame.sort_values(by, *, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last', ignore_index=False, key=None)
参数:
例子:
import pandas as pd # 创建 DataFrame 数组 data = {"名字":["张三", "李四", "我是小白呀"], "年龄":[25, 32, 18]} # 创建字典 df = pd.DataFrame(data) # 由字典创建 DataFrame 数组 print(df) # 调试输出 # DataFrame 排序 df = df.sort_values(by="年龄") # 通过布尔条件筛选特定数据 df.reset_index(inplace=True) # 重新索引 print("排序: \n{}".format(df)) # 调试输出
注: 通过df.reset_index(inplace=True), DataFrame 数组会进行重新索引.
我们可以对 DataFrame 数字进行各种聚合操作.
例子:
import pandas as pd # 创建 DataFrame 数组 data = {"名字":["张三", "李四", "我是小白呀"], "年龄":[25, 32, 18]} # 创建字典 df = pd.DataFrame(data) # 由字典创建 DataFrame 数组 print(df) # 调试输出 # DataFrame 聚合 mean = df["年龄"].mean() # 通过布尔条件筛选特定数据 print("平均年龄:", mean) # 调试输出
输出结果:
名字 年龄 0 张三 25 1 李四 32 2 我是小白呀 18 平均年龄: 25.0
import pandas as pd # 创建 DataFrame 数组 data = {"名字":["张三", "李四", "我是小白呀"], "年龄":[25, 32, 18]} # 创建字典 df = pd.DataFrame(data) # 由字典创建 DataFrame 数组 print(df) # 调试输出 # 添加列 data["成绩"] = [78, 82, 60] # 添加一个新的列, 成绩 print(df) # 调试输出 # 删除列 del data["年龄"] # 删除年龄列 print(df)
输出结果:
名字 年龄 0 张三 25 1 李四 32 2 我是小白呀 18 名字 年龄 0 张三 25 1 李四 32 2 我是小白呀 18 名字 年龄 0 张三 25 1 李四 32 2 我是小白呀 18
我们经常会遇到需要从 csv 文件中加塞数据的情况. Pandas 中提供了read_csv方法, 使得我们从 csv 文件中加载数据变得非常简单.
格式:
pandas.read_csv(filepath_or_buffer, *, sep=_NoDefault.no_default, delimiter=None, header='infer', names=_NoDefault.no_default, index_col=None, usecols=None, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, skipfooter=0, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=None, infer_datetime_format=_NoDefault.no_default, keep_date_col=False, date_parser=_NoDefault.no_default, date_format=None, dayfirst=False, cache_dates=True, iterator=False, chunksize=None, compression='infer', thousands=None, decimal='.', lineterminator=None, quotechar='"', quoting=0, doublequote=True, escapechar=None, comment=None, encoding=None, encoding_errors='strict', dialect=None, on_bad_lines='error', delim_whitespace=False, low_memory=True, memory_map=False, float_precision=None, storage_options=None, dtype_backend=_NoDefault.no_default)
参数:
例子:
import pandas as pd # 读取 txt/csv data = pd.read_csv("test.txt", header=None, names=["链接"]) print(data) # 调试输出
输出结果:
链接 0 http://melanz.phorum.pl/viewtopic.php?f=7&t=64041 1 http://www.reo14.moe.go.th/phpBB3/viewtopic.ph... 2 https://www.xroxy.com/xorum/viewtopic.php?p=30... 3 http://armasow.forumbb.ru/viewtopic.php?id=840... 4 http://telecom.liveforums.ru/viewtopic.php?id=... 5 http://www.crpsc.org.br/forum/viewtopic.php?f=... 6 http://community.getvideostream.com/topic/4803... 7 http://www.shop.minecraftcommand.science/forum... 8 https://www.moddingway.com/forums/thread-31914... 9 https://webhitlist.com/forum/topics/main-featu...
例子:
df = pd.read_excel('path_to_file.xlsx')
在 DataFrame 中, 我们可以用过一些函数来查看 DataFrame 数据的基本结构和内容.
常用函数:
例子:
import pandas as pd # 读取数据 data = pd.read_csv("students.txt", header=None) print(data.info()) # 显示总览, 包括每列的数据类型和非空值的数量 print(data.head()) # 显示前 5 行 print(data.tail()) # 显示后 5 行 print(data.describe()) # 显示基本统计信息
调试输出:
RangeIndex: 131 entries, 0 to 130 Data columns (total 2 columns): 0 131 non-null object 1 131 non-null object dtypes: object(2) memory usage: 2.1+ KB None 0 1 0 c1235666 Fink-Nottle Augustus James 1 c3456765 O'Mahoney Geoffrey 2 c8732719 De Leo Victoria Margaret 3 c9676814 Thompson Sabrina 4 c4418710 Heck Kevin 0 1 126 c6060052 Long Marilyn 127 c2390980 Martz Perry Tony William 128 c5456142 Wilson Christine Mabel 129 c1036678 Bunch Richard Frank 130 c8306065 Hartley Marcel Jonathan Philip 0 1 count 131 131 unique 131 127 top c3827371 Bush Thomas freq 1 2
大多情况下, 数据可能不总是完整的, 所以我们要处理数据丢失. Pandas 提供了多种处理缺失数据的方法.
在 Pandas 中, 缺失值通常表示为 “NaN” (Not a Number). 我们可以使用isnull()函数或者isna()函数来列出数据中的缺失值.
以下数据就缺失 Fare 列中的几个值:
PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S
例子:
import pandas as pd # 读取数据 data = pd.read_csv("train.csv") print(data) # 调试输出每列的缺失值 print(data.isnull().sum())
输出结果:
PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S 4 5 0 3 ... 8.0500 NaN S 5 6 0 3 ... 8.4583 NaN Q 6 7 0 1 ... 51.8625 E46 S 7 8 0 3 ... 21.0750 NaN S 8 9 1 3 ... 11.1333 NaN S 9 10 1 2 ... 30.0708 NaN C 10 11 1 3 ... 16.7000 G6 S 11 12 1 1 ... 26.5500 C103 S 12 13 0 3 ... 8.0500 NaN S 13 14 0 3 ... 31.2750 NaN S 14 15 0 3 ... 7.8542 NaN S 15 16 1 2 ... 16.0000 NaN S 16 17 0 3 ... 29.1250 NaN Q 17 18 1 2 ... 13.0000 NaN S 18 19 0 3 ... 18.0000 NaN S 19 20 1 3 ... 7.2250 NaN C 20 21 0 2 ... 26.0000 NaN S 21 22 1 2 ... 13.0000 D56 S 22 23 1 3 ... 8.0292 NaN Q 23 24 1 1 ... 35.5000 A6 S 24 25 0 3 ... 21.0750 NaN S 25 26 1 3 ... 31.3875 NaN S 26 27 0 3 ... 7.2250 NaN C 27 28 0 1 ... 263.0000 C23 C25 C27 S 28 29 1 3 ... 7.8792 NaN Q 29 30 0 3 ... 7.8958 NaN S .. ... ... ... ... ... ... ... 861 862 0 2 ... 11.5000 NaN S 862 863 1 1 ... 25.9292 D17 S 863 864 0 3 ... 69.5500 NaN S 864 865 0 2 ... 13.0000 NaN S 865 866 1 2 ... 13.0000 NaN S 866 867 1 2 ... 13.8583 NaN C 867 868 0 1 ... 50.4958 A24 S 868 869 0 3 ... 9.5000 NaN S 869 870 1 3 ... 11.1333 NaN S 870 871 0 3 ... 7.8958 NaN S 871 872 1 1 ... 52.5542 D35 S 872 873 0 1 ... 5.0000 B51 B53 B55 S 873 874 0 3 ... 9.0000 NaN S 874 875 1 2 ... 24.0000 NaN C 875 876 1 3 ... 7.2250 NaN C 876 877 0 3 ... 9.8458 NaN S 877 878 0 3 ... 7.8958 NaN S 878 879 0 3 ... 7.8958 NaN S 879 880 1 1 ... 83.1583 C50 C 880 881 1 2 ... 26.0000 NaN S 881 882 0 3 ... 7.8958 NaN S 882 883 0 3 ... 10.5167 NaN S 883 884 0 2 ... 10.5000 NaN S 884 885 0 3 ... 7.0500 NaN S 885 886 0 3 ... 29.1250 NaN Q 886 887 0 2 ... 13.0000 NaN S 887 888 1 1 ... 30.0000 B42 S 888 889 0 3 ... 23.4500 NaN S 889 890 1 1 ... 30.0000 C148 C 890 891 0 3 ... 7.7500 NaN Q [891 rows x 12 columns] PassengerId 0 Survived 0 Pclass 0 Name 0 Sex 0 Age 177 SibSp 0 Parch 0 Ticket 0 Fare 0 Cabin 687 Embarked 2 dtype: int64
df.dropna()可以帮助我们删除数据中所有缺失的行.
例子:
import pandas as pd import numpy as np # 创建一个模拟数据集 data = { 'Product': ['Apple', 'Banana', 'Cherry', 'Date', 'Fig', 'Grape', 'Mango', 'Watermelon'], 'Price': [1, 0.5, np.nan, 0.75, np.nan, 2.5, 1.2, np.nan], 'Date_sold': [np.nan, '2023-01-15', '2023-01-16', '2023-01-17', '2023-01-18', '2023-01-19', np.nan, '2023-01-21'] } df = pd.DataFrame(data) print("原始数据:") print(df) # 删除任何含有 NaN 的行 df_dropped = df.dropna() print("\n删除含有 NaN 后的数据:") print(df_dropped)
输出结果:
原始数据: Product Price Date_sold 0 Apple 1.00 NaN 1 Banana 0.50 2023-01-15 2 Cherry NaN 2023-01-16 3 Date 0.75 2023-01-17 4 Fig NaN 2023-01-18 5 Grape 2.50 2023-01-19 6 Mango 1.20 NaN 7 Watermelon NaN 2023-01-21 删除含有 NaN 后的数据: Product Price Date_sold 1 Banana 0.50 2023-01-15 3 Date 0.75 2023-01-17 5 Grape 2.50 2023-01-19
df.fillna()帮助我们使用指定的值填充缺失数据.
例子:
import pandas as pd import numpy as np # 创建一个模拟数据集 data = { 'Product': ['Apple', 'Banana', 'Cherry', 'Date', 'Fig', 'Grape', 'Mango', 'Watermelon'], 'Price': [1, 0.5, np.nan, 0.75, np.nan, 2.5, 1.2, np.nan], 'Date_sold': [np.nan, '2023-01-15', '2023-01-16', '2023-01-17', '2023-01-18', '2023-01-19', np.nan, '2023-01-21'] } df = pd.DataFrame(data) print("原始数据:") print(df) # 使用固定值填充 df1 = df.copy() df1['Price'].fillna("1", inplace=True) print("\n使用固定值填充后的数据:") print(df1) # 使用前一个值填充 df2 = df.copy() df2['Price'].fillna(method='ffill', inplace=True) print("\n使用前一个值填充后的数据:") print(df2) # 使用平均值填充 df3 = df.copy() df3['Price'].fillna(df3['Price'].mean(), inplace=True) print("\n使用平均值填充后的数据:") print(df3)
输出结果:
原始数据: Product Price Date_sold 0 Apple 1.00 NaN 1 Banana 0.50 2023-01-15 2 Cherry NaN 2023-01-16 3 Date 0.75 2023-01-17 4 Fig NaN 2023-01-18 5 Grape 2.50 2023-01-19 6 Mango 1.20 NaN 7 Watermelon NaN 2023-01-21 使用固定值填充后的数据: Product Price Date_sold 0 Apple 1 NaN 1 Banana 0.5 2023-01-15 2 Cherry 1 2023-01-16 3 Date 0.75 2023-01-17 4 Fig 1 2023-01-18 5 Grape 2.5 2023-01-19 6 Mango 1.2 NaN 7 Watermelon 1 2023-01-21 使用前一个值填充后的数据: Product Price Date_sold 0 Apple 1.00 NaN 1 Banana 0.50 2023-01-15 2 Cherry 0.50 2023-01-16 3 Date 0.75 2023-01-17 4 Fig 0.75 2023-01-18 5 Grape 2.50 2023-01-19 6 Mango 1.20 NaN 7 Watermelon 1.20 2023-01-21 使用平均值填充后的数据: Product Price Date_sold 0 Apple 1.00 NaN 1 Banana 0.50 2023-01-15 2 Cherry 1.19 2023-01-16 3 Date 0.75 2023-01-17 4 Fig 1.19 2023-01-18 5 Grape 2.50 2023-01-19 6 Mango 1.20 NaN 7 Watermelon 1.19 2023-01-21
去重:
df.drop.duplicates()
数据转换:
df['column_name'] = df['column_name'].astype('new_type') # 转换数据类型 df['new_column'] = df['column1'] + df['column2']
Pandas 中 inplace 参数在很多函数中都会有, 它的作用是: 是否在原对象基础上进行修改.
inplace 中 True 和 False 的意思:
例子:
# 以下两行代码意思相同 df.dropna(inplace=True) # 直接对 df 对象进行修改 df_dropped = df.dropna(inplace=True) # 对 df 进行修改并返回对象
inplace 参数在函数中默认是 False,即创建新的对象进行修改, 原对象不变, 和深复制和浅复制有些类似.
contact()函数可以帮助我们连接两个或者多个数据.
格式:
df.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=None, copy=True)
参数:
例子:
import pandas as pd # 初始化 DataFrame 数组 df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'], 'B': ['B0', 'B1', 'B2']}) df2 = pd.DataFrame({'A': ['A3', 'A4', 'A5'], 'B': ['B3', 'B4', 'B5']}) # 调试输出 print(df1) print(df2) # 进行 concat 连接 result = pd.concat([df1, df2]) print(result)
调试输出:
A B 0 A0 B0 1 A1 B1 2 A2 B2 A B 0 A3 B3 1 A4 B4 2 A5 B5 A B 0 A0 B0 1 A1 B1 2 A2 B2 0 A3 B3 1 A4 B4 2 A5 B5
```merge()``函数也可以帮助我们进行合并操作, 类似于 SQL 的 JOIN.
例子:
import pandas as pd # 初始化 DataFrame 数组 left = pd.DataFrame({'key': ['K0', 'K1', 'K2'], 'A': ['A0', 'A1', 'A2'], 'B': ['B0', 'B1', 'B2']}) right = pd.DataFrame({'key': ['K0', 'K1', 'K2'], 'C': ['C0', 'C1', 'C2'], 'D': ['D0', 'D1', 'D2']}) # 调试输出 print(left) print(right) # 使用 merge 拼接 result = pd.merge(left, right, on='key') print(result)
输出结果:
key A B 0 K0 A0 B0 1 K1 A1 B1 2 K2 A2 B2 key C D 0 K0 C0 D0 1 K1 C1 D1 2 K2 C2 D2 key A B C D 0 K0 A0 B0 C0 D0 1 K1 A1 B1 C1 D1 2 K2 A2 B2 C2 D2
使用groupby()可以将数组框按列值分组, 然后对每个组应用聚合函数.
常见的聚合函数:
例 1:
import pandas as pd # 初始化 DataFrame 数组 df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar'], 'B': [1, 2, 3, 4], 'C': [2.0, 3.0, 4.0, 5.0]}) print(df) # 聚合求和 grouped = df.groupby('A').sum() print(grouped)
调试输出:
A B C 0 foo 1 2.0 1 bar 2 3.0 2 foo 3 4.0 3 bar 4 5.0 B C A bar 6 8.0 foo 4 6.0
例 2, 关于全球员工薪水的数据集:
import pandas as pd # 数据集 data = { 'Country': ['USA', 'India', 'UK', 'USA', 'India', 'UK', 'USA', 'India'], 'Employee': ['Sam', 'Amit', 'John', 'Alice', 'Alok', 'Bob', 'Charlie', 'Deepak'], 'Salary': [70000, 45000, 60000, 80000, 50000, 55000, 85000, 65000] } # 初始化 DataFrame df = pd.DataFrame(data) print(df) # 使用 goupby() 根据国家计算平均薪水 salary_by_country = df.groupby("Country")["Salary"].mean() print("平均薪水:", salary_by_country) # 使用 groupby() 计算每个国家的员工数 employee_by_country = df.groupby("Country")["Employee"].count() print("员工数量: \n{}",format(employee_by_country)) # 多重聚合 result = df.groupby("Country")['Salary'].agg(['mean', 'median', 'sum', 'max', 'min']) print(result)
输出结果:
Country Employee Salary 0 USA Sam 70000 1 India Amit 45000 2 UK John 60000 3 USA Alice 80000 4 India Alok 50000 5 UK Bob 55000 6 USA Charlie 85000 7 India Deepak 65000 平均薪水: Country India 53333.333333 UK 57500.000000 USA 78333.333333 Name: Salary, dtype: float64 员工数量: {} Country India 3 UK 2 USA 3 Name: Employee, dtype: int64 mean median sum max min Country India 53333.333333 50000 160000 65000 45000 UK 57500.000000 57500 115000 60000 55000 USA 78333.333333 80000 235000 85000 70000
Pandas 提供了 “datatime” 和 “timedelta” 类型, 用于处理时间数据.
例子:
import pandas as pd # 时间序列分析 data = pd.to_datetime(['2023-01-01', '2023-02-01']) print(data) # 调试输出
输出结果:
DatetimeIndex(['2023-01-01', '2023-02-01'], dtype='datetime64[ns]', freq=None)
我们可以通过 Pandas 进行基本的数据可视化.
Pandas 除了能进行数据处理和分析的功能外, 还提供了简单直观的绘制方法:
使用plot绘制线图:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 生成示例数据 date_rng = pd.date_range(start='2020-01-01', end='2020-12-31', freq='D') df = pd.DataFrame(date_rng, columns=['date']) df['data'] = np.random.randint(0, 100, size=(len(date_rng))) df.set_index('date', inplace=True) df.plot(figsize=(10, 6)) plt.title('Time Series Data Visualization') plt.ylabel('Random Data') plt.show()
输出结果:
使用hist()绘制直方图:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 生成示例数据 date_rng = pd.date_range(start='2020-01-01', end='2020-12-31', freq='D') df = pd.DataFrame(date_rng, columns=['date']) df['data'] = np.random.randint(0, 100, size=(len(date_rng))) # 绘制直方图 df['data'].hist(bins=30, figsize=(10, 6)) plt.title('Histogram Data Visualization') plt.xlabel('Random Data') plt.ylabel('Frequency') plt.show()
输出结果:
使用boxplot()绘制箱线图:
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 生成示例数据 date_rng = pd.date_range(start='2020-01-01', end='2020-12-31', freq='D') df = pd.DataFrame(date_rng, columns=['date']) df['data'] = np.random.randint(0, 100, size=(len(date_rng))) # 绘制箱线图 df.boxplot(column='data', figsize=(6, 10)) plt.title('Boxplot Data Visualization') plt.ylabel('Random Data') plt.show()
输出结果:
Pandas 在数据分析中的重要性. Pandas 是 Python 数据分析中的一个不可或缺的库. 通过 Pandas, 数据科学家和数据分析师能够轻松的读取, 处理, 分析和可视化数据.
首先,我们介绍了 Pandas 的核心数据结构——Series 和 DataFrame,它们分别为一维和二维数据提供了丰富的操作和功能。接着,我们详细讨论了如何对数据进行索引、选择和修改,使数据处理变得简单高效。
在数据清洗部分,我们学习了各种数据清洗技巧,如处理缺失值、重复数据和字符串操作。这些都是数据预处理过程中的关键步骤,对于后续的分析和模型建立至关重要。
之后,我们深入了解了数据的聚合、转换和过滤。通过对数据的分组和汇总,我们可以获得有关数据的有趣洞察和统计信息。
最后,我们探索了 Pandas 的高级特性,如数据的合并、重塑、透视以及如何处理大数据和性能优化。这些技巧可以帮助我们更好地组织和优化代码,使其更具可读性和效率。
总的来说,Pandas 是一个功能强大、灵活且高效的工具,无论你是数据初学者还是经验丰富的分析师,都应该深入学习和掌握它。希望本篇博客能为你的数据分析之旅提供有价值的参考和指导。继续探索、学习和实践,让数据的魅力助你走得更远!
泰坦尼克号数据集。这个数据集包含了泰坦尼克号上乘客的信息和他们是否在沉船事故中生还。
数据描述:
下载泰坦尼克号数据集:点此下载
使用 Pandas 读取下载的 CSV 文件。
数据初步探索:
数据筛选与操作:
创建一个新列 IsChild,标记年龄小于18岁的乘客。
数据统计与聚合:
数据清洗:
数据可视化:
import pandas as pd from matplotlib import pyplot as plt # 读取数据 data = pd.read_csv("train.csv") print(data) # 显示基本信息 print(data.info()) print(data.describe()) print(data.isnull().sum()) # 调试输出缺失值 # 填充缺失 data["Age"].fillna(data["Age"].mean(), inplace=True) # 填充平均值 data['Cabin'].fillna('Unknown', inplace=True) print(data.isnull().sum()) # 调试输出缺失值 # 数据筛选与操作 selected_data = data[['Pclass', 'Sex', 'Survived']] first_class_females = data[(data['Pclass'] == 1) & (data['Sex'] == 'female')] # 标记18岁以下的乘客 data['IsChild'] = data['Age'].apply(lambda x: 1 if x < 18 else 0) # 数据统计与聚合 female_survival_rate = data[data['Sex'] == 'female']['Survived'].mean() print(f"Female Survival Rate: {female_survival_rate}") class_survival_rates = data.groupby('Pclass')['Survived'].mean() print(class_survival_rates) pivot_table = data.pivot_table('Survived', index='Sex', columns='Pclass') print(pivot_table) # 数据清洗 data['Sex'] = data['Sex'].map({'male': 0, 'female': 1}) # 将 Sex 列转为数值型 # 数据可视化 class_survival_rates.plot(kind='bar', title='Survival Rates by Pclass') plt.ylabel('Survival Rate') plt.show() data['Age'].hist(bins=30, edgecolor='black') plt.title('Age Distribution') plt.xlabel('Age') plt.ylabel('Number of Passengers') plt.show() data['Fare'].plot(kind='box') plt.title('Fare Distribution') plt.ylabel('Fare') plt.show()
输出结果:
PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S 4 5 0 3 ... 8.0500 NaN S 5 6 0 3 ... 8.4583 NaN Q 6 7 0 1 ... 51.8625 E46 S 7 8 0 3 ... 21.0750 NaN S 8 9 1 3 ... 11.1333 NaN S 9 10 1 2 ... 30.0708 NaN C 10 11 1 3 ... 16.7000 G6 S 11 12 1 1 ... 26.5500 C103 S 12 13 0 3 ... 8.0500 NaN S 13 14 0 3 ... 31.2750 NaN S 14 15 0 3 ... 7.8542 NaN S 15 16 1 2 ... 16.0000 NaN S 16 17 0 3 ... 29.1250 NaN Q 17 18 1 2 ... 13.0000 NaN S 18 19 0 3 ... 18.0000 NaN S 19 20 1 3 ... 7.2250 NaN C 20 21 0 2 ... 26.0000 NaN S 21 22 1 2 ... 13.0000 D56 S 22 23 1 3 ... 8.0292 NaN Q 23 24 1 1 ... 35.5000 A6 S 24 25 0 3 ... 21.0750 NaN S 25 26 1 3 ... 31.3875 NaN S 26 27 0 3 ... 7.2250 NaN C 27 28 0 1 ... 263.0000 C23 C25 C27 S 28 29 1 3 ... 7.8792 NaN Q 29 30 0 3 ... 7.8958 NaN S .. ... ... ... ... ... ... ... 861 862 0 2 ... 11.5000 NaN S 862 863 1 1 ... 25.9292 D17 S 863 864 0 3 ... 69.5500 NaN S 864 865 0 2 ... 13.0000 NaN S 865 866 1 2 ... 13.0000 NaN S 866 867 1 2 ... 13.8583 NaN C 867 868 0 1 ... 50.4958 A24 S 868 869 0 3 ... 9.5000 NaN S 869 870 1 3 ... 11.1333 NaN S 870 871 0 3 ... 7.8958 NaN S 871 872 1 1 ... 52.5542 D35 S 872 873 0 1 ... 5.0000 B51 B53 B55 S 873 874 0 3 ... 9.0000 NaN S 874 875 1 2 ... 24.0000 NaN C 875 876 1 3 ... 7.2250 NaN C 876 877 0 3 ... 9.8458 NaN S 877 878 0 3 ... 7.8958 NaN S 878 879 0 3 ... 7.8958 NaN S 879 880 1 1 ... 83.1583 C50 C 880 881 1 2 ... 26.0000 NaN S 881 882 0 3 ... 7.8958 NaN S 882 883 0 3 ... 10.5167 NaN S 883 884 0 2 ... 10.5000 NaN S 884 885 0 3 ... 7.0500 NaN S 885 886 0 3 ... 29.1250 NaN Q 886 887 0 2 ... 13.0000 NaN S 887 888 1 1 ... 30.0000 B42 S 888 889 0 3 ... 23.4500 NaN S 889 890 1 1 ... 30.0000 C148 C 890 891 0 3 ... 7.7500 NaN Q [891 rows x 12 columns]RangeIndex: 891 entries, 0 to 890 Data columns (total 12 columns): PassengerId 891 non-null int64 Survived 891 non-null int64 Pclass 891 non-null int64 Name 891 non-null object Sex 891 non-null object Age 714 non-null float64 SibSp 891 non-null int64 Parch 891 non-null int64 Ticket 891 non-null object Fare 891 non-null float64 Cabin 204 non-null object Embarked 889 non-null object dtypes: float64(2), int64(5), object(5) memory usage: 83.6+ KB None PassengerId Survived Pclass ... SibSp Parch Fare count 891.000000 891.000000 891.000000 ... 891.000000 891.000000 891.000000 mean 446.000000 0.383838 2.308642 ... 0.523008 0.381594 32.204208 std 257.353842 0.486592 0.836071 ... 1.102743 0.806057 49.693429 min 1.000000 0.000000 1.000000 ... 0.000000 0.000000 0.000000 25% 223.500000 0.000000 2.000000 ... 0.000000 0.000000 7.910400 50% 446.000000 0.000000 3.000000 ... 0.000000 0.000000 14.454200 75% 668.500000 1.000000 3.000000 ... 1.000000 0.000000 31.000000 max 891.000000 1.000000 3.000000 ... 8.000000 6.000000 512.329200 [8 rows x 7 columns] PassengerId 0 Survived 0 Pclass 0 Name 0 Sex 0 Age 177 SibSp 0 Parch 0 Ticket 0 Fare 0 Cabin 687 Embarked 2 dtype: int64 PassengerId 0 Survived 0 Pclass 0 Name 0 Sex 0 Age 0 SibSp 0 Parch 0 Ticket 0 Fare 0 Cabin 0 Embarked 2 dtype: int64 Female Survival Rate: 0.7420382165605095 Pclass 1 0.629630 2 0.472826 3 0.242363 Name: Survived, dtype: float64 Pclass 1 2 3 Sex female 0.968085 0.921053 0.500000 male 0.368852 0.157407 0.135447