与电子表格的对比#

考虑到许多潜在的 pandas 用户对 Excel 等电子表格程序有一定的了解,本页面旨在提供一些示例,说明如何使用 pandas 执行各种电子表格操作。本页面将使用 Excel 的术语并链接到其文档,但很多内容在 Google Sheets、LibreOffice Calc、Apple Numbers 和其他兼容 Excel 的电子表格软件中也相同/相似。

如果您是 pandas 的新手,您可能需要先阅读10 分钟学会 pandas以熟悉该库。

按照惯例,我们如下导入 pandas 和 NumPy

In [1]: import pandas as pd

In [2]: import numpy as np

数据结构#

通用术语翻译#

pandas

Excel

DataFrame

工作表

Series

索引

行标题

NaN

空单元格

DataFrame#

pandas 中的 DataFrame 类似于 Excel 的工作表。虽然 Excel 工作簿可以包含多个工作表,但 pandas 的 DataFrame 是独立存在的。

Series#

Series 是代表 DataFrame 中某一列的数据结构。使用 Series 类似于引用电子表格中的一列。

Index#

每个 DataFrameSeries 都有一个 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=Truecopy=False 关键字参数

df.replace(5, inplace=True)

关于弃用和删除大多数方法的 inplacecopy(例如 dropna),除了极少数方法(包括 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 中,您将 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 通过双击或使用“打开”菜单打开各种 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 中,您可以直接对整个列执行操作。

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 中,过滤是通过图形菜单完成的。

Screenshot showing filtering of the total_bill column to values greater than 10

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 对象的 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 逻辑#

假设我们要创建一个名为 bucket 的列,其值根据 total_bill 是否小于或大于 10 美元而为 lowhigh

在电子表格中,可以使用条件公式进行逻辑比较。我们将使用一个公式 =IF(A2 < 10, "low", "high"),将其拖动到新 bucket 列的所有单元格中。

Screenshot showing the formula from above in a bucket column of the tips spreadsheet

在 pandas 中,可以使用 numpywhere 方法实现相同操作。

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 中通过日期时间属性

给定电子表格 A 列和 B 列中的 date1date2,您可能拥有这些公式

公式

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]

按值排序#

在电子表格中,排序是通过排序对话框完成的。

Screenshot of dialog from Excel showing sorting by the sex then total_bill 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]

字符串处理#

查找字符串长度#

在电子表格中,可以使用 LEN 函数查找文本中的字符数。这可以与 TRIM 函数结合使用以删除额外的空格。

=LEN(TRIM(A2))

您可以使用 Series.str.len() 查找字符字符串的长度。在 Python 3 中,所有字符串都是 Unicode 字符串。len 包括尾随空格。使用 lenrstrip 来排除尾随空格。

In [32]: tips["time"].str.len()
Out[32]: 
67     6
92     6
111    6
145    5
135    5
      ..
182    6
156    6
59     6
212    6
170    6
Name: time, Length: 244, dtype: int64

In [33]: tips["time"].str.rstrip().str.len()
Out[33]: 
67     6
92     6
111    6
145    5
135    5
      ..
182    6
156    6
59     6
212    6
170    6
Name: time, Length: 244, dtype: int64

请注意,这仍然会包含字符串中的多个空格,因此并非 100% 等效。

查找子字符串的位置#

FIND 电子表格函数返回子字符串的位置,第一个字符为 1

Screenshot of FIND formula being used in Excel

您可以使用 Series.str.find() 方法在字符串列中查找字符的位置。find 搜索子字符串的第一个位置。如果找到子字符串,该方法返回其位置。如果未找到,则返回 -1。请记住,Python 索引是从零开始的。

In [34]: tips["sex"].str.find("ale")
Out[34]: 
67     3
92     3
111    3
145    3
135    3
      ..
182    1
156    1
59     1
212    1
170    1
Name: sex, Length: 244, dtype: int64

按位置提取子字符串#

电子表格提供了 MID 公式,用于从给定位置提取子字符串。要获取第一个字符

=MID(A2,1,1)

在 pandas 中,您可以使用 [] 表示法通过位置来提取子字符串。请记住,Python 索引是从零开始的。

In [35]: tips["sex"].str[0:1]
Out[35]: 
67     F
92     F
111    F
145    F
135    F
      ..
182    M
156    M
59     M
212    M
170    M
Name: sex, Length: 244, dtype: str

提取第 n 个单词#

在 Excel 中,您可以使用“文本到列”向导来拆分文本并检索特定列。(请注意,也可以通过公式实现。)

在 pandas 中提取单词的最简单方法是按空格分割字符串,然后按索引引用单词。请注意,如果您需要更强大的方法,也可以使用。

In [36]: firstlast = pd.DataFrame({"String": ["John Smith", "Jane Cook"]})

In [37]: firstlast["First_Name"] = firstlast["String"].str.split(" ", expand=True)[0]

In [38]: firstlast["Last_Name"] = firstlast["String"].str.rsplit(" ", expand=True)[1]

In [39]: firstlast
Out[39]: 
       String First_Name Last_Name
0  John Smith       John     Smith
1   Jane Cook       Jane      Cook

更改大小写#

电子表格提供了 UPPERLOWERPROPER 函数,分别用于将文本转换为大写、小写和首字母大写。

等效的 pandas 方法是 Series.str.upper()Series.str.lower()Series.str.title()

In [40]: firstlast = pd.DataFrame({"string": ["John Smith", "Jane Cook"]})

In [41]: firstlast["upper"] = firstlast["string"].str.upper()

In [42]: firstlast["lower"] = firstlast["string"].str.lower()

In [43]: firstlast["title"] = firstlast["string"].str.title()

In [44]: firstlast
Out[44]: 
       string       upper       lower       title
0  John Smith  JOHN SMITH  john smith  John Smith
1   Jane Cook   JANE COOK   jane cook   Jane Cook

合并#

以下表格将用于合并示例

In [45]: df1 = pd.DataFrame({"key": ["A", "B", "C", "D"], "value": np.random.randn(4)})

In [46]: df1
Out[46]: 
  key     value
0   A  0.469112
1   B -0.282863
2   C -1.509059
3   D -1.135632

In [47]: df2 = pd.DataFrame({"key": ["B", "D", "D", "E"], "value": np.random.randn(4)})

In [48]: df2
Out[48]: 
  key     value
0   B  1.212112
1   D -0.173215
2   D  0.119209
3   E -1.044236

在 Excel 中,可以使用 VLOOKUP合并表

Screenshot showing a VLOOKUP formula between two tables in Excel, with some values being filled in and others with "#N/A"

pandas DataFrame 有一个 merge() 方法,它提供了类似的功能。数据不必提前排序,并且可以通过 how 关键字实现不同的连接类型。

In [49]: inner_join = df1.merge(df2, on=["key"], how="inner")

In [50]: inner_join
Out[50]: 
  key   value_x   value_y
0   B -0.282863  1.212112
1   D -1.135632 -0.173215
2   D -1.135632  0.119209

In [51]: left_join = df1.merge(df2, on=["key"], how="left")

In [52]: left_join
Out[52]: 
  key   value_x   value_y
0   A  0.469112       NaN
1   B -0.282863  1.212112
2   C -1.509059       NaN
3   D -1.135632 -0.173215
4   D -1.135632  0.119209

In [53]: right_join = df1.merge(df2, on=["key"], how="right")

In [54]: right_join
Out[54]: 
  key   value_x   value_y
0   B -0.282863  1.212112
1   D -1.135632 -0.173215
2   D -1.135632  0.119209
3   E       NaN -1.044236

In [55]: outer_join = df1.merge(df2, on=["key"], how="outer")

In [56]: outer_join
Out[56]: 
  key   value_x   value_y
0   A  0.469112       NaN
1   B -0.282863  1.212112
2   C -1.509059       NaN
3   D -1.135632 -0.173215
4   D -1.135632  0.119209
5   E       NaN -1.044236

mergeVLOOKUP 具有许多优势

  • 查找值不需要是查找表的第一列

  • 如果匹配多行,则每场比赛都有一行,而不是只有第一场

  • 它将包含查找表中的所有列,而不是仅指定的一列

  • 它支持更复杂的连接操作

其他注意事项#

填充柄#

在一组单元格中创建一系列遵循固定模式的数字。在电子表格中,这可以通过输入第一个数字后按住 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 中,我们对数据透视表使用以下配置

Screenshot showing a PivotTable in Excel, using sex as the column, size as the rows, then average tip as the values

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(编号为 01 等),我们可以使用 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]