PYTHON
使用Pandas探索和清理新数据集的技巧,附带代码示例和解释
使用新数据集的关键部分是理解它。
了解数据中有哪些列,原始数据类型是什么以及数据的描述性统计信息等基本信息,对于正确地处理数据非常重要。
Pandas有很多内置的方法,您可以在笔记本电脑中立即使用它们来探索数据。当您进行数据探索的初始步骤时,您可以同时开始使您的数据可用于进一步分析或准备训练机器学习模型。
在本文中,让我们使用一组大学数据来回答以下问题,以展示在同时探索和清理数据时它的样子:
- 哪些大学只提供面对面的出勤?
- 最古老和最新创立的大学之间的年限是多少?
我们将主要使用loc方法与其他几个内置的Pandas方法相结合来回答这些问题。首先,我们将快速查看loc方法的作用,然后逐个步骤地进行这些示例。
请随意在笔记本电脑中跟随!您可以从Kaggle下载数据集,该数据集可在Open Data Commons公共领域奉献和许可证(PDDL)v1.0下免费使用。然后导入并运行以下内容,我们就可以开始了!
import pandas as pddf_raw = pd.read_csv("Top-Largest-Universities.csv")
loc方法的简要介绍
基本上,Pandas中的loc方法允许您根据给定条件选择目标DataFrame的一部分行或列。
您可以向loc传递几种不同的输入。例如,当您想根据其索引选择DataFrame的切片时,您可以使用在使用列表时与Python相同的语法,例如:[start:stop]。但是,在本文中,我们将主要专注于使用具有条件语句的loc。如果您以前使用过SQL,那么这类似于编写查询的WHERE部分以过滤数据。
一般来说,以这种方式使用loc将如下所示:
df.loc[df["column"] == "condition"]
这将返回列等于条件的数据子集。
接下来,让我们继续一些使用loc方法的实际示例,以进行探索性数据分析,看看您还可以做什么。
使用Pandas loc方法回答大学出勤问题
哪些大学只提供面对面的出勤?
首先,让我们看看如何使用loc选择数据的一部分以在进一步分析中使用。
如果数据已经干净,您可能会认为要回答问题,您可以仅在该列上使用groupby来计算提供面对面出勤的机构数量。在Pandas中执行此操作如下:
df.groupby("Distance / In-Person")["Institution"].count()

不幸的是,“Distance / In-Person”列的值并不是很干净。空格存在一些问题,一些机构同时提供远程和面对面出勤,尽管记录方式没有标准化。
首先,我们可以重命名该列,以便它不包含任何空格或特殊字符。
df = df.rename(columns={"Distance / In-Person": "distance_or_in_person"})
接下来,我们可以通过选择 DataFrame 中的所有列来验证更改是否生效。
df.columns

现在,所有列至少都没有任何空格或特殊字符。如果您想要进一步标准化它,可以将所有其他列更改为小写,但我们现在将跳过这个步骤。
早些时候,我们在目标列上执行了分组操作,并计算了每个机构的值。同样达到相同结果的另一种方法是使用 Pandas 中的 value_counts 方法。这将返回一个 Series,其中包含您在其上调用的目标列的唯一值的计数。
df["distance_or_in_person"].value_counts()

您会注意到,在这种情况下,这一次我们不需要再次调用“Institutions”列,但这是因为在我们的原始 DataFrame 中,每一行都代表一个机构。
现在,为了清理这一列,以便将同时提供面对面和远程出席的机构的值分组为一个值,我们可以利用 loc 列来过滤那些值并将 distance_or_in_person 列的值赋给一个新值“Both”。
df.loc[ ~df["distance_or_in_person"].isin(["In-Person", "Distance"]), "distance_or_in_person"] = "Both"
在这里,我们使用 ~ 运算符过滤当前不等于“In-Person”或“Distance”的 distance_or_in_person 列,然后选择 distance_or_in_person 列。然后将其设置为“Both”,这会更新原始 DataFrame。我们可以通过再次检查 DataFrame 来验证更改:
df.head()

现在,您将看到更新后的列仅包含三个可能的值,我们可以再次调用 value_counts 来获取我们最初的问题的答案:
df["distance_or_in_person"].value_counts()

现在,我们知道根据清理后的数据,有 59 所大学仅提供面对面出席。
有了这个新条件,如果您想知道哪些具体机构提供面对面出席,我们可以再次使用 loc 方法过滤 DataFrame,然后使用 tolist 方法将所有值存储到 Python 列表中:
df.loc[df["distance_or_in_person"] == "In-Person"]["Institution"].tolist()

我们现在有了一个机构列表,但是有一些特殊字符需要删除。Python 中的“\xa0”表示不间断空格,这意味着我们可以使用 Pandas 中的 strip 方法来消除它,该方法消除字符串值两端的空格。
我们可以编辑我们的初始 tolist 代码,以便像这样清理最终输出:
df.loc[df["distance_or_in_person"] == "In-Person"]["Institution"].str.strip().tolist()

现在,我们有了一个仅提供现场出席的大学最终名单!
最古老和最新成立的大学之间的年份范围是多少?
接下来,让我们使用 loc 和一些其他本机 Pandas 方法来过滤我们的 DataFrame 以回答特定的数据分析问题。
我们可以先看一下成立栏目,以了解我们正在使用的内容:
df["Founded"]

看起来我们有一个仅充满年份值的栏目。由于我们想要将日期相互比较,因此我们可以将该栏目转换为 datetime 类型以使分析更容易。
pd.to_datetime(df["Founded"])

然而,对该栏目使用 to_datetime 方法会出现 ParserError。
看起来有一个字符串与我们最初从成立栏目中看到的内容不匹配。我们可以使用 loc 方法来过滤 DataFrame,以筛选出具体等于我们在 ParserError 中看到的 founded 值的行:
df.loc[df["Founded"] == "1948 and 2014"]

显然有一所大学有两个不同的成立年份。并且,现在我们知道了行的索引(9),还有一个使用 loc 方法来特定地过滤 DataFrame 中的索引值的示例:
df.loc[9]

看起来这是 DataFrame 中唯一一行,其中“Founded”栏目的值有多个年份。
根据您想要做什么来处理数据,您可以尝试通过选择一个年份(第一个成立日期)或通过为此机构创建两行,因此两个成立日期在不同的行上来清理数据。
在这种情况下,既然我们只是处理这些数据以回答一个简单的问题(这个数据集中机构的成立日期范围是多少),我们可以像这样删除这一行:
df.drop(9).head(10) # 删除该行

检查结果 DataFrame,可以看到具有索引“9”的行,其成立栏目有多个值,不再在表格中。通过在删除行之后重新分配 DataFrame,可以使删除生效:
df = df.drop(9)
接下来,我们可以再次在 Founded 栏目上执行 to_datetime 方法,看看会发生什么。
pd.to_datetime(df["Founded"], errors="coerce")

实际上,这里还有另一个错误,这就是为什么我包括了 errors="coerce",以确保如果有任何其他问题将字符串转换为 datetime 类型,则该值将变为 null。
最后,我们可以将创立时间的 datetime 类型版本分配给一个新的列。然后,为了检查机构的最早成立日期,我们可以使用 Python 中的 min 方法:
df["founded_date"] = pd.to_datetime(df["Founded"], errors="coerce")min(df["founded_date"])

您可以使用 min 和 max 方法查看 founded_date 列的最早和最新时间戳,以获取最旧和最新大学之间的年份范围。
在这里,我意识到如果我们只需要回答一个简单的问题,我们可以更快地完成所有这些工作。我们可以将该列转换为整数类型,然后从彼此的最大值和最小值中减去以获取范围,而不是将其转换为 datetime 类型。
df["Founded"] = df["Founded"].astype("int")max(df["Founded"]) - min(df["Founded"])
这将输出 719。
您不应总是采用简单的方法,只将年份列转换为整数。如果你想做一些更复杂的分析,或者你特别处理时间序列日期时,如果你能正确清理你的数据并将日期列转换为日期时间类型,那么会增加很多附加值。然而,如果你只需要快速分析,那么简单地找到解决问题的最快方法而不是“最佳”方法,可以节省你的时间和头痛的麻烦。
您可以使用许多不同的 Pandas 方法组合来清理和分析您的日期。 loc 方法是多功能的,允许您使用不同的方法来过滤、切片和更新您的 DataFrame,以使其适用于您想要解决的特定问题和问题。
清理数据是一个迭代的过程,与探索数据相辅相成。我希望您在前进过程中会发现使用 loc 的这些示例对您的自己的分析有所帮助。
如果您喜欢我的内容,请考虑关注我并使用下面的推荐链接注册成为小猪AI会员。它每月只需 5 美元,您将获得对小猪AI上的所有内容的无限访问权限。使用我的链接注册让我能够赚取一小部分佣金。如果您已经注册并关注了我,非常感谢您的支持!
使用我的推荐链接加入小猪AI —— Byron Dolon
作为小猪AI会员,您的会员费的一部分将用于支付您阅读的作家,您将获得对每个故事的完全访问权…
byrondolon.medium.com
更多我的作品: – 3种有效的方法来通过子字符串过滤Pandas DataFrame列 – 作为数据分析师的实用技巧 – 用Python改进您的数据可视化:使用堆叠条形图 – 使用.loc在Pandas中进行条件选择和赋值 – 用Pandas理解您的数据的5(及半)行代码