Pandas 2.2 中文官方教程和指南(四)(2)https://developer.aliyun.com/article/1509880
其他考虑事项
填充手柄
在一定的一系列单元格中创建一个遵循特定模式的数字序列。在电子表格中,这可以通过输入第一个数字后按住 Shift+拖动,或者输入前两个或三个值然后拖动来完成。
这可以通过创建一个系列并将其分配给所需的单元格来实现。
In [57]: df = pd.DataFrame({"AAA": [1] * 8, "BBB": list(range(0, 8))}) In [58]: df Out[58]: AAA BBB 0 1 0 1 1 1 2 1 2 3 1 3 4 1 4 5 1 5 6 1 6 7 1 7 In [59]: series = list(range(1, 5)) In [60]: series Out[60]: [1, 2, 3, 4] In [61]: df.loc[2:5, "AAA"] = series In [62]: df Out[62]: AAA BBB 0 1 0 1 1 1 2 1 2 3 2 3 4 3 4 5 4 5 6 1 6 7 1 7
删除重复项
Excel 内置功能可用于删除重复值。在 pandas 中通过 drop_duplicates()
支持此功能。
In [63]: df = pd.DataFrame( ....: { ....: "class": ["A", "A", "A", "B", "C", "D"], ....: "student_count": [42, 35, 42, 50, 47, 45], ....: "all_pass": ["Yes", "Yes", "Yes", "No", "No", "Yes"], ....: } ....: ) ....: In [64]: df.drop_duplicates() Out[64]: class student_count all_pass 0 A 42 Yes 1 A 35 Yes 3 B 50 No 4 C 47 No 5 D 45 Yes In [65]: df.drop_duplicates(["class", "student_count"]) Out[65]: class student_count all_pass 0 A 42 Yes 1 A 35 Yes 3 B 50 No 4 C 47 No 5 D 45 Yes
透视表
电子表格的数据透视表可以通过 数据重塑和数据透视表 在 pandas 中复制。再次使用 tips
数据集,让我们找到按照客人数量和服务员性别的平均小费。
在 Excel 中,我们使用以下配置进行数据透视表:
pandas 中的等价物:
In [66]: pd.pivot_table( ....: tips, values="tip", index=["size"], columns=["sex"], aggfunc=np.average ....: ) ....: Out[66]: sex Female Male size 1 1.276667 1.920000 2 2.528448 2.614184 3 3.250000 3.476667 4 4.021111 4.172143 5 5.140000 3.750000 6 4.600000 5.850000
添加一行
假设我们使用的是 RangeIndex
(编号为 0
、1
等),我们可以使用 concat()
将一行添加到 DataFrame
的底部。
In [67]: df Out[67]: class student_count all_pass 0 A 42 Yes 1 A 35 Yes 2 A 42 Yes 3 B 50 No 4 C 47 No 5 D 45 Yes In [68]: new_row = pd.DataFrame([["E", 51, True]], ....: columns=["class", "student_count", "all_pass"]) ....: In [69]: pd.concat([df, new_row]) Out[69]: class student_count all_pass 0 A 42 Yes 1 A 35 Yes 2 A 42 Yes 3 B 50 No 4 C 47 No 5 D 45 Yes 0 E 51 True
查找和替换
Excel 的查找对话框将逐个匹配的单元格显示出来。在 pandas 中,此操作通常针对整个列或 DataFrame
一次性进行,通过 条件表达式。
In [70]: tips Out[70]: total_bill tip sex smoker day time size 67 1.07 1.00 Female Yes Sat Dinner 1 92 3.75 1.00 Female Yes Fri Dinner 2 111 5.25 1.00 Female No Sat Dinner 1 145 6.35 1.50 Female No Thur Lunch 2 135 6.51 1.25 Female No Thur Lunch 2 .. ... ... ... ... ... ... ... 182 43.35 3.50 Male Yes Sun Dinner 3 156 46.17 5.00 Male No Sun Dinner 6 59 46.27 6.73 Male No Sat Dinner 4 212 46.33 9.00 Male No Sat Dinner 4 170 48.81 10.00 Male Yes Sat Dinner 3 [244 rows x 7 columns] In [71]: tips == "Sun" Out[71]: total_bill tip sex smoker day time size 67 False False False False False False False 92 False False False False False False False 111 False False False False False False False 145 False False False False False False False 135 False False False False False False False .. ... ... ... ... ... ... ... 182 False False False False True False False 156 False False False False True False False 59 False False False False False False False 212 False False False False False False False 170 False False False False False False False [244 rows x 7 columns] In [72]: tips["day"].str.contains("S") Out[72]: 67 True 92 False 111 True 145 False 135 False ... 182 True 156 True 59 True 212 True 170 True Name: day, Length: 244, dtype: bool
pandas 的 replace()
类似于 Excel 的 全部替换
。
In [73]: tips.replace("Thu", "Thursday") Out[73]: total_bill tip sex smoker day time size 67 1.07 1.00 Female Yes Sat Dinner 1 92 3.75 1.00 Female Yes Fri Dinner 2 111 5.25 1.00 Female No Sat Dinner 1 145 6.35 1.50 Female No Thur Lunch 2 135 6.51 1.25 Female No Thur Lunch 2 .. ... ... ... ... ... ... ... 182 43.35 3.50 Male Yes Sun Dinner 3 156 46.17 5.00 Male No Sun Dinner 6 59 46.27 6.73 Male No Sat Dinner 4 212 46.33 9.00 Male No Sat Dinner 4 170 48.81 10.00 Male Yes Sat Dinner 3 [244 rows x 7 columns]
数据结构
一般术语翻译
pandas | Excel |
DataFrame |
工作表 |
Series |
列 |
Index |
行标题 |
行 | 行 |
NaN |
空单元格 |
DataFrame
在 pandas 中,DataFrame
类似于 Excel 的工作表。虽然 Excel 工作簿可以包含多个工作表,但 pandas 的 DataFrame
是独立存在的。
Series
Series
是代表 DataFrame
的一列的数据结构。与处理电子表格的列类似,处理 Series
。
Index
每个 DataFrame
和 Series
都有一个 Index
,这些是数据的 行 上的标签。在 pandas 中,如果没有指定索引,则默认使用 RangeIndex
(第一行 = 0,第二行 = 1,依此类推),类似于电子表格中的行标题/行号。
在 pandas 中,索引可以设置为一个(或多个)唯一值,这类似于在工作表中使用作为行标识符的列。与大多数电子表格不同,这些Index
值实际上可以用于引用行。 (请注意,Excel 中可以使用结构化引用执行此操作。)例如,在电子表格中,您可以引用第一行为A1:Z1
,而在 pandas 中,您可以使用populations.loc['Chicago']
。
索引值也是持久的,因此如果重新排序DataFrame
的行,则特定行的标签不会更改。
查看 索引文档以获取更多关于如何有效使用Index
的信息。
副本 vs. 原地操作
大多数 pandas 操作都返回Series
/DataFrame
的副本。要使更改“生效”,您需要将其分配给一个新变量:
sorted_df = df.sort_values("col1")
或覆盖原始的:
df = df.sort_values("col1")
注意
对于某些方法,您会看到一个可用的inplace=True
或copy=False
关键字参数:
df.replace(5, inplace=True)
关于大多数方法(例如dropna
)的逐步弃用和移除inplace
和copy
存在活跃讨论,除了极少数方法(包括replace
)。在写时复制的情况下,这两个关键字将不再需要。提案可以在这里找到。
一般术语翻译
pandas | Excel |
DataFrame |
工作表 |
Series |
列 |
Index |
行标题 |
行 | 行 |
NaN |
空单元格 |
DataFrame
在 pandas 中,DataFrame
类似于 Excel 中的工作表。虽然 Excel 工作簿可以包含多个工作表,但 pandas 的DataFrame
存在独立于此。
Series
Series
是表示DataFrame
的一列的数据结构。与引用电子表格列类似,与Series
一起工作。
Index
每个DataFrame
和Series
都有一个Index
,这些是数据的行上的标签。在 pandas 中,如果未指定索引,则默认使用RangeIndex
(第一行= 0,第二行= 1,依此类推),类似于电子表格中的行标题/数字。
在 pandas 中,索引可以设置为一个(或多个)唯一值,这类似于在工作表中使用作为行标识符的列。与大多数电子表格不同,这些Index
值实际上可以用于引用行。 (请注意,Excel 中可以使用结构化引用执行此操作。)例如,在电子表格中,您可以引用第一行为A1:Z1
,而在 pandas 中,您可以使用populations.loc['Chicago']
。
索引值也是持久的,因此如果重新排列DataFrame
中的行,则特定行的标签不会更改。
查看索引文档以了解如何有效地使用Index
。
复制与原地操作
大多数 pandas 操作返回Series
/DataFrame
的副本。要使更改“生效”,您需要将其分配给一个新变量:
sorted_df = df.sort_values("col1")
或覆盖原始数据:
df = df.sort_values("col1")
注意
您将看到一些方法可用的inplace=True
或copy=False
关键字参数:
df.replace(5, inplace=True)
关于在大多数方法(例如dropna
)中弃用和删除inplace
和copy
的讨论正在进行中,除了一小部分方法(包括replace
)。在 Copy-on-Write 的上下文中,这两个关键字将不再是必需的。提案可以在这里找到。
数据输入/输出
从值构建 DataFrame
在电子表格中,可以直接在单元格中输入值。
pandas 的DataFrame
可以以许多不同的方式构建,但对于少量值来说,通常将其指定为 Python 字典是方便的,其中键是列名,值是数据。
In [3]: df = pd.DataFrame({"x": [1, 3, 5], "y": [2, 4, 6]}) In [4]: df Out[4]: x y 0 1 2 1 3 4 2 5 6
读取外部数据
Excel 和 pandas 都可以从各种来源以各种格式导入数据。
CSV
让我们加载并显示来自 pandas 测试的tips数据集,这是一个 CSV 文件。在 Excel 中,您将下载然后打开 CSV 文件。在 pandas 中,您将 URL 或 CSV 文件的本地路径传递给read_csv()
:
In [5]: url = ( ...: "https://raw.githubusercontent.com/pandas-dev" ...: "/pandas/main/pandas/tests/io/data/csv/tips.csv" ...: ) ...: In [6]: tips = pd.read_csv(url) In [7]: tips Out[7]: total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4 .. ... ... ... ... ... ... ... 239 29.03 5.92 Male No Sat Dinner 3 240 27.18 2.00 Female Yes Sat Dinner 2 241 22.67 2.00 Male Yes Sat Dinner 2 242 17.82 1.75 Male No Sat Dinner 2 243 18.78 3.00 Female No Thur Dinner 2 [244 rows x 7 columns]
像Excel 的文本导入向导一样,read_csv
可以接受多个参数来指定数据应该如何解析。例如,如果数据是制表符分隔的,并且没有列名,那么 pandas 命令将是:
tips = pd.read_csv("tips.csv", sep="\t", header=None) # alternatively, read_table is an alias to read_csv with tab delimiter tips = pd.read_table("tips.csv", header=None)
Excel 文件
Excel 通过双击或使用打开菜单打开各种 Excel 文件格式。在 pandas 中,您可以使用特殊方法来读取和写入 Excel 文件。
让我们首先根据上面示例中的tips
数据框创建一个新的 Excel 文件:
tips.to_excel("./tips.xlsx")
如果您希望随后访问tips.xlsx
文件中的数据,可以使用以下方式将其读入模块中
tips_df = pd.read_excel("./tips.xlsx", index_col=0)
您刚刚使用 pandas 读取了一个 Excel 文件!
限制输出
电子表格程序一次只会显示一个屏幕的数据,然后允许您滚动,因此实际上没有必要限制输出。在 pandas 中,您需要更多地考虑如何控制您的DataFrame
的显示方式。
默认情况下,pandas 会截断大型DataFrame
的输出以显示第一行和最后一行。这可以通过更改 pandas 选项,或使用DataFrame.head()
或DataFrame.tail()
来覆盖。
In [8]: tips.head(5) Out[8]: total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4
导出数据
默认情况下,桌面电子表格软件将保存为其相应的文件格式(.xlsx
,.ods
等)。但是,您可以保存为其他文件格式。
pandas 可以创建 Excel 文件,CSV,或者其他多种格式。
从值构建 DataFrame
在电子表格中,可以直接在单元格中输入值。
可以以许多不同的方式构建 pandas DataFrame
,但对于少量值,通常将其指定为 Python 字典是方便的,其中键是列名,值是数据。
In [3]: df = pd.DataFrame({"x": [1, 3, 5], "y": [2, 4, 6]}) In [4]: df Out[4]: x y 0 1 2 1 3 4 2 5 6
读取外部数据
Excel和 pandas 都可以从各种来源以各种格式导入数据。
CSV
让我们加载并显示来自 pandas 测试的tips数据集,这是一个 CSV 文件。在 Excel 中,您将下载然后打开 CSV 文件。在 pandas 中,您将 CSV 文件的 URL 或本地路径传递给read_csv()
:
In [5]: url = ( ...: "https://raw.githubusercontent.com/pandas-dev" ...: "/pandas/main/pandas/tests/io/data/csv/tips.csv" ...: ) ...: In [6]: tips = pd.read_csv(url) In [7]: tips Out[7]: total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4 .. ... ... ... ... ... ... ... 239 29.03 5.92 Male No Sat Dinner 3 240 27.18 2.00 Female Yes Sat Dinner 2 241 22.67 2.00 Male Yes Sat Dinner 2 242 17.82 1.75 Male No Sat Dinner 2 243 18.78 3.00 Female No Thur Dinner 2 [244 rows x 7 columns]
像 Excel 的文本导入向导 一样,read_csv
可以使用多个参数来指定数据应如何解析。例如,如果数据是以制表符分隔的,并且没有列名,那么 pandas 命令将是:
tips = pd.read_csv("tips.csv", sep="\t", header=None) # alternatively, read_table is an alias to read_csv with tab delimiter tips = pd.read_table("tips.csv", header=None)
Excel 文件
通过双击或使用打开菜单打开各种 Excel 文件格式。在 pandas 中,您使用特殊的方法来读取和写入 Excel 文件。
首先,基于上面示例中的 tips
数据框,让我们创建一个新的 Excel 文件:
tips.to_excel("./tips.xlsx")
如果您希望随后访问 tips.xlsx
文件中的数据,可以使用以下命令将其读入您的模块中:
tips_df = pd.read_excel("./tips.xlsx", index_col=0)
您刚刚使用 pandas 读取了一个 Excel 文件!
CSV
让我们加载并显示来自 pandas 测试的 tips 数据集,这是一个 CSV 文件。在 Excel 中,您将下载然后打开 CSV。在 pandas 中,您将 CSV 文件的 URL 或本地路径传递给 read_csv()
:
In [5]: url = ( ...: "https://raw.githubusercontent.com/pandas-dev" ...: "/pandas/main/pandas/tests/io/data/csv/tips.csv" ...: ) ...: In [6]: tips = pd.read_csv(url) In [7]: tips Out[7]: total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4 .. ... ... ... ... ... ... ... 239 29.03 5.92 Male No Sat Dinner 3 240 27.18 2.00 Female Yes Sat Dinner 2 241 22.67 2.00 Male Yes Sat Dinner 2 242 17.82 1.75 Male No Sat Dinner 2 243 18.78 3.00 Female No Thur Dinner 2 [244 rows x 7 columns]
像 Excel 的文本导入向导 一样,read_csv
可以使用多个参数来指定数据应如何解析。例如,如果数据是以制表符分隔的,并且没有列名,那么 pandas 命令将是:
tips = pd.read_csv("tips.csv", sep="\t", header=None) # alternatively, read_table is an alias to read_csv with tab delimiter tips = pd.read_table("tips.csv", header=None)
Excel 文件
通过双击或使用打开菜单打开各种 Excel 文件格式。在 pandas 中,您使用特殊的方法来读取和写入 Excel 文件。
首先,基于上面示例中的 tips
数据框,让我们创建一个新的 Excel 文件:
tips.to_excel("./tips.xlsx")
如果您希望随后访问 tips.xlsx
文件中的数据,可以使用以下命令将其读入您的模块中:
tips_df = pd.read_excel("./tips.xlsx", index_col=0)
您刚刚使用 pandas 读取了一个 Excel 文件!
限制输出
电子表格程序一次只会显示一个屏幕的数据,然后允许您滚动,因此实际上不需要限制输出。在 pandas 中,您需要更多地思考如何控制您的 DataFrame
的显示。
默认情况下,pandas 会截断大型 DataFrame
的输出,以显示第一行和最后一行。可以通过更改 pandas 选项,或使用 DataFrame.head()
或 DataFrame.tail()
来覆盖此行为。
In [8]: tips.head(5) Out[8]: total_bill tip sex smoker day time size 0 16.99 1.01 Female No Sun Dinner 2 1 10.34 1.66 Male No Sun Dinner 3 2 21.01 3.50 Male No Sun Dinner 3 3 23.68 3.31 Male No Sun Dinner 2 4 24.59 3.61 Female No Sun Dinner 4
数据导出
默认情况下,桌面电子表格软件将保存为其相应的文件格式(.xlsx
,.ods
等)。但是,您可以保存到其他文件格式。
pandas 可以创建 Excel 文件,CSV,或许多其他格式。
数据操作
列上的操作
在电子表格中,公式通常在单个单元格中创建,然后拖动到其他单元格以计算其他列的值。在 pandas 中,您可以直接对整个列进行操作。
通过在 DataFrame
中指定单独的 Series
来提供向量化操作。新列可以以相同的方式分配。DataFrame.drop()
方法从 DataFrame
中删除列。
In [9]: tips["total_bill"] = tips["total_bill"] - 2 In [10]: tips["new_bill"] = tips["total_bill"] / 2 In [11]: tips Out[11]: total_bill tip sex smoker day time size new_bill 0 14.99 1.01 Female No Sun Dinner 2 7.495 1 8.34 1.66 Male No Sun Dinner 3 4.170 2 19.01 3.50 Male No Sun Dinner 3 9.505 3 21.68 3.31 Male No Sun Dinner 2 10.840 4 22.59 3.61 Female No Sun Dinner 4 11.295 .. ... ... ... ... ... ... ... ... 239 27.03 5.92 Male No Sat Dinner 3 13.515 240 25.18 2.00 Female Yes Sat Dinner 2 12.590 241 20.67 2.00 Male Yes Sat Dinner 2 10.335 242 15.82 1.75 Male No Sat Dinner 2 7.910 243 16.78 3.00 Female No Thur Dinner 2 8.390 [244 rows x 8 columns] In [12]: tips = tips.drop("new_bill", axis=1)
请注意,我们不需要逐个单元格地告诉它执行减法 - pandas 为我们处理了这个过程。请参阅如何根据现有列创建新列。
过滤
在 Excel 中,过滤是通过一个图形菜单完成的。
DataFrame 可以以多种方式进行过滤;其中最直观的是使用布尔索引。
In [13]: tips[tips["total_bill"] > 10] Out[13]: total_bill tip sex smoker day time size 0 14.99 1.01 Female No Sun Dinner 2 2 19.01 3.50 Male No Sun Dinner 3 3 21.68 3.31 Male No Sun Dinner 2 4 22.59 3.61 Female No Sun Dinner 4 5 23.29 4.71 Male No Sun Dinner 4 .. ... ... ... ... ... ... ... 239 27.03 5.92 Male No Sat Dinner 3 240 25.18 2.00 Female Yes Sat Dinner 2 241 20.67 2.00 Male Yes Sat Dinner 2 242 15.82 1.75 Male No Sat Dinner 2 243 16.78 3.00 Female No Thur Dinner 2 [204 rows x 7 columns]
上述语句只是将一系列 True
/False
对象传递给 DataFrame,返回所有具有 True
的行。
In [14]: is_dinner = tips["time"] == "Dinner" In [15]: is_dinner Out[15]: 0 True 1 True 2 True 3 True 4 True ... 239 True 240 True 241 True 242 True 243 True Name: time, Length: 244, dtype: bool In [16]: is_dinner.value_counts() Out[16]: time True 176 False 68 Name: count, dtype: int64 In [17]: tips[is_dinner] Out[17]: total_bill tip sex smoker day time size 0 14.99 1.01 Female No Sun Dinner 2 1 8.34 1.66 Male No Sun Dinner 3 2 19.01 3.50 Male No Sun Dinner 3 3 21.68 3.31 Male No Sun Dinner 2 4 22.59 3.61 Female No Sun Dinner 4 .. ... ... ... ... ... ... ... 239 27.03 5.92 Male No Sat Dinner 3 240 25.18 2.00 Female Yes Sat Dinner 2 241 20.67 2.00 Male Yes Sat Dinner 2 242 15.82 1.75 Male No Sat Dinner 2 243 16.78 3.00 Female No Thur Dinner 2 [176 rows x 7 columns]
If/then 逻辑
假设我们想要根据 total_bill
是小于还是大于 10 美元来创建一个 bucket
列,其值分别为 low
和 high
。
在电子表格中,可以使用条件公式进行逻辑比较。我们将一个 =IF(A2 < 10, "low", "high")
的公式拖动到一个新的 bucket
列的所有单元格中。
在 pandas 中,可以使用numpy
中的where
方法来完成相同的操作。
In [18]: tips["bucket"] = np.where(tips["total_bill"] < 10, "low", "high") In [19]: tips Out[19]: total_bill tip sex smoker day time size bucket 0 14.99 1.01 Female No Sun Dinner 2 high 1 8.34 1.66 Male No Sun Dinner 3 low 2 19.01 3.50 Male No Sun Dinner 3 high 3 21.68 3.31 Male No Sun Dinner 2 high 4 22.59 3.61 Female No Sun Dinner 4 high .. ... ... ... ... ... ... ... ... 239 27.03 5.92 Male No Sat Dinner 3 high 240 25.18 2.00 Female Yes Sat Dinner 2 high 241 20.67 2.00 Male Yes Sat Dinner 2 high 242 15.82 1.75 Male No Sat Dinner 2 high 243 16.78 3.00 Female No Thur Dinner 2 high [244 rows x 8 columns]
日期功能
本节将提到“日期”,但时间戳处理方式类似。
我们可以将日期功能分为两部分:解析和输出。在电子表格中,日期值通常会自动解析,尽管如果需要,可以使用DATEVALUE函数。在 pandas 中,您需要显式地将纯文本转换为 datetime 对象,可以在从 CSV 读取时或在 DataFrame 中进行转换。
解析后,电子表格以默认格式显示日期,尽管格式可以更改。在 pandas 中,您通常希望在进行计算时将日期保留为datetime
对象。在电子表格中,通过日期函数和在 pandas 中通过 datetime 属性来输出日期的部分(如年份)。
在电子表格的列A
和B
中给定date1
和date2
,您可能会有以下公式:
列名 | 公式 |
date1_year |
=YEAR(A2) |
date2_month |
=MONTH(B2) |
date1_next |
=DATE(YEAR(A2),MONTH(A2)+1,1) |
months_between |
=DATEDIF(A2,B2,"M") |
下面显示了等效的 pandas 操作。
In [20]: tips["date1"] = pd.Timestamp("2013-01-15") In [21]: tips["date2"] = pd.Timestamp("2015-02-15") In [22]: tips["date1_year"] = tips["date1"].dt.year In [23]: tips["date2_month"] = tips["date2"].dt.month In [24]: tips["date1_next"] = tips["date1"] + pd.offsets.MonthBegin() In [25]: tips["months_between"] = tips["date2"].dt.to_period("M") - tips[ ....: "date1" ....: ].dt.to_period("M") ....: In [26]: tips[ ....: ["date1", "date2", "date1_year", "date2_month", "date1_next", "months_between"] ....: ] ....: Out[26]: date1 date2 date1_year date2_month date1_next months_between 0 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 1 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 2 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 3 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 4 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> .. ... ... ... ... ... ... 239 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 240 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 241 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 242 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 243 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> [244 rows x 6 columns]
更多详细信息,请参阅时间序列/日期功能。
选择列
在电子表格中,您可以通过以下方式选择所需的列:
由于电子表格列通常是在标题行中命名的,重命名列只需简单地更改该第一个单元格中的文本。
下面展示了 pandas 中相同的操作。
保留特定列
In [27]: tips[["sex", "total_bill", "tip"]] Out[27]: sex total_bill tip 0 Female 14.99 1.01 1 Male 8.34 1.66 2 Male 19.01 3.50 3 Male 21.68 3.31 4 Female 22.59 3.61 .. ... ... ... 239 Male 27.03 5.92 240 Female 25.18 2.00 241 Male 20.67 2.00 242 Male 15.82 1.75 243 Female 16.78 3.00 [244 rows x 3 columns]
删除一列
In [28]: tips.drop("sex", axis=1) Out[28]: total_bill tip smoker day time size 0 14.99 1.01 No Sun Dinner 2 1 8.34 1.66 No Sun Dinner 3 2 19.01 3.50 No Sun Dinner 3 3 21.68 3.31 No Sun Dinner 2 4 22.59 3.61 No Sun Dinner 4 .. ... ... ... ... ... ... 239 27.03 5.92 No Sat Dinner 3 240 25.18 2.00 Yes Sat Dinner 2 241 20.67 2.00 Yes Sat Dinner 2 242 15.82 1.75 No Sat Dinner 2 243 16.78 3.00 No Thur Dinner 2 [244 rows x 6 columns]
重命名列
In [29]: tips.rename(columns={"total_bill": "total_bill_2"}) Out[29]: total_bill_2 tip sex smoker day time size 0 14.99 1.01 Female No Sun Dinner 2 1 8.34 1.66 Male No Sun Dinner 3 2 19.01 3.50 Male No Sun Dinner 3 3 21.68 3.31 Male No Sun Dinner 2 4 22.59 3.61 Female No Sun Dinner 4 .. ... ... ... ... ... ... ... 239 27.03 5.92 Male No Sat Dinner 3 240 25.18 2.00 Female Yes Sat Dinner 2 241 20.67 2.00 Male Yes Sat Dinner 2 242 15.82 1.75 Male No Sat Dinner 2 243 16.78 3.00 Female No Thur Dinner 2 [244 rows x 7 columns]
按值排序
电子表格中的排序通过排序对话框完成。
pandas 有一个DataFrame.sort_values()
方法,接受一个要排序的列列表。
In [30]: tips = tips.sort_values(["sex", "total_bill"]) In [31]: tips Out[31]: total_bill tip sex smoker day time size 67 1.07 1.00 Female Yes Sat Dinner 1 92 3.75 1.00 Female Yes Fri Dinner 2 111 5.25 1.00 Female No Sat Dinner 1 145 6.35 1.50 Female No Thur Lunch 2 135 6.51 1.25 Female No Thur Lunch 2 .. ... ... ... ... ... ... ... 182 43.35 3.50 Male Yes Sun Dinner 3 156 46.17 5.00 Male No Sun Dinner 6 59 46.27 6.73 Male No Sat Dinner 4 212 46.33 9.00 Male No Sat Dinner 4 170 48.81 10.00 Male Yes Sat Dinner 3 [244 rows x 7 columns]
列操作
在电子表格中,公式通常在单独的单元格中创建,然后拖动到其他单元格中以计算其他列的值。在 pandas 中,您可以直接对整列进行操作。
pandas 通过在DataFrame
中指定单独的Series
提供矢量化操作。新列可以以相同的方式分配。DataFrame.drop()
方法从DataFrame
中删除列。
In [9]: tips["total_bill"] = tips["total_bill"] - 2 In [10]: tips["new_bill"] = tips["total_bill"] / 2 In [11]: tips Out[11]: total_bill tip sex smoker day time size new_bill 0 14.99 1.01 Female No Sun Dinner 2 7.495 1 8.34 1.66 Male No Sun Dinner 3 4.170 2 19.01 3.50 Male No Sun Dinner 3 9.505 3 21.68 3.31 Male No Sun Dinner 2 10.840 4 22.59 3.61 Female No Sun Dinner 4 11.295 .. ... ... ... ... ... ... ... ... 239 27.03 5.92 Male No Sat Dinner 3 13.515 240 25.18 2.00 Female Yes Sat Dinner 2 12.590 241 20.67 2.00 Male Yes Sat Dinner 2 10.335 242 15.82 1.75 Male No Sat Dinner 2 7.910 243 16.78 3.00 Female No Thur Dinner 2 8.390 [244 rows x 8 columns] In [12]: tips = tips.drop("new_bill", axis=1)
请注意,我们不需要逐个单元格地告诉它执行减法 - pandas 会为我们处理。参见如何从现有列派生新列。
过滤
DataFrames 可以以多种方式进行过滤;其中最直观的是使用布尔索引。
In [13]: tips[tips["total_bill"] > 10] Out[13]: total_bill tip sex smoker day time size 0 14.99 1.01 Female No Sun Dinner 2 2 19.01 3.50 Male No Sun Dinner 3 3 21.68 3.31 Male No Sun Dinner 2 4 22.59 3.61 Female No Sun Dinner 4 5 23.29 4.71 Male No Sun Dinner 4 .. ... ... ... ... ... ... ... 239 27.03 5.92 Male No Sat Dinner 3 240 25.18 2.00 Female Yes Sat Dinner 2 241 20.67 2.00 Male Yes Sat Dinner 2 242 15.82 1.75 Male No Sat Dinner 2 243 16.78 3.00 Female No Thur Dinner 2 [204 rows x 7 columns]
上述语句只是简单地将True
/False
对象的Series
传递给 DataFrame,返回所有具有True
的行。
In [14]: is_dinner = tips["time"] == "Dinner" In [15]: is_dinner Out[15]: 0 True 1 True 2 True 3 True 4 True ... 239 True 240 True 241 True 242 True 243 True Name: time, Length: 244, dtype: bool In [16]: is_dinner.value_counts() Out[16]: time True 176 False 68 Name: count, dtype: int64 In [17]: tips[is_dinner] Out[17]: total_bill tip sex smoker day time size 0 14.99 1.01 Female No Sun Dinner 2 1 8.34 1.66 Male No Sun Dinner 3 2 19.01 3.50 Male No Sun Dinner 3 3 21.68 3.31 Male No Sun Dinner 2 4 22.59 3.61 Female No Sun Dinner 4 .. ... ... ... ... ... ... ... 239 27.03 5.92 Male No Sat Dinner 3 240 25.18 2.00 Female Yes Sat Dinner 2 241 20.67 2.00 Male Yes Sat Dinner 2 242 15.82 1.75 Male No Sat Dinner 2 243 16.78 3.00 Female No Thur Dinner 2 [176 rows x 7 columns]
If/then 逻辑
假设我们想要根据total_bill
是低于还是高于$10 来创建一个bucket
列,值为low
和high
。
在电子表格中,可以使用条件公式进行逻辑比较。我们会使用一个公式=IF(A2 < 10, "low", "high")
,拖动到新的bucket
列中的所有单元格。
在 pandas 中,可以使用numpy
的where
方法来完成相同的操作。
In [18]: tips["bucket"] = np.where(tips["total_bill"] < 10, "low", "high") In [19]: tips Out[19]: total_bill tip sex smoker day time size bucket 0 14.99 1.01 Female No Sun Dinner 2 high 1 8.34 1.66 Male No Sun Dinner 3 low 2 19.01 3.50 Male No Sun Dinner 3 high 3 21.68 3.31 Male No Sun Dinner 2 high 4 22.59 3.61 Female No Sun Dinner 4 high .. ... ... ... ... ... ... ... ... 239 27.03 5.92 Male No Sat Dinner 3 high 240 25.18 2.00 Female Yes Sat Dinner 2 high 241 20.67 2.00 Male Yes Sat Dinner 2 high 242 15.82 1.75 Male No Sat Dinner 2 high 243 16.78 3.00 Female No Thur Dinner 2 high [244 rows x 8 columns]
日期功能
本节将涉及“日期”,但时间戳处理方式类似。
我们可以将日期功能分为两部分:解析和输出。在电子表格中,日期值通常会自动解析,尽管如果需要的话可以使用 DATEVALUE 函数。在 pandas 中,您需要显式地将纯文本转换为日期时间对象,可以在 读取 CSV 时 或者 在 DataFrame 中 进行转换。
一旦解析,电子表格会以默认格式显示日期,尽管 格式可以更改。在 pandas 中,通常在进行计算时希望将日期保留为 datetime
对象。在电子表格中,输出日期的 部分(如年份)是通过 日期函数 实现的,在 pandas 中则通过 datetime 属性 实现。
在电子表格的列 A
和 B
中给定 date1
和 date2
,您可能会有以下公式:
列名 | 公式 |
date1_year |
=YEAR(A2) |
date2_month |
=MONTH(B2) |
date1_next |
=DATE(YEAR(A2),MONTH(A2)+1,1) |
months_between |
=DATEDIF(A2,B2,"M") |
等效的 pandas 操作如下所示。
In [20]: tips["date1"] = pd.Timestamp("2013-01-15") In [21]: tips["date2"] = pd.Timestamp("2015-02-15") In [22]: tips["date1_year"] = tips["date1"].dt.year In [23]: tips["date2_month"] = tips["date2"].dt.month In [24]: tips["date1_next"] = tips["date1"] + pd.offsets.MonthBegin() In [25]: tips["months_between"] = tips["date2"].dt.to_period("M") - tips[ ....: "date1" ....: ].dt.to_period("M") ....: In [26]: tips[ ....: ["date1", "date2", "date1_year", "date2_month", "date1_next", "months_between"] ....: ] ....: Out[26]: date1 date2 date1_year date2_month date1_next months_between 0 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 1 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 2 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 3 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 4 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> .. ... ... ... ... ... ... 239 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 240 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 241 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 242 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> 243 2013-01-15 2015-02-15 2013 2 2013-02-01 <25 * MonthEnds> [244 rows x 6 columns]
更多详细信息,请��阅 时间序列/日期功能。
Pandas 2.2 中文官方教程和指南(四)(4)https://developer.aliyun.com/article/1509883