【Pandas】① Pandas 数据处理基础

介绍

        Pandas 是非常著名的开源数据处理库,我们可以通过它完成对数据集进行快速读取、转换、过滤、分析等一系列操作。除此之外,Pandas 拥有强大的缺失数据处理与数据透视功能,可谓是数据预处理中的必备利器。

知识点

  • 数据类型
  • 数据读取
  • 数据选择
  • 数据删减
  • 数据填充

       Pandas 是非常著名的开源数据处理库,其基于 NumPy 开发,该工具是 Scipy 生态中为了解决数据分析任务而设计。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的函数和方法。

        特有的数据结构是 Pandas 的优势和核心。简单来讲,我们可以将任意格式的数据转换为 Pandas 的数据类型,并使用 Pandas 提供的一系列方法进行转换、操作,最终得到我们期望的结果。

        所以,我们首先需要了解并熟悉 Pandas 支持的数据类型。

数据类型

        Pandas 的数据类型主要有以下几种,它们分别是:Series(一维数组),DataFrame(二维数组),Panel(三维数组),Panel4D(四维数组),PanelND(更多维数组)。其中 Series 和 DataFrame 应用的最为广泛,几乎占据了使用频率 90% 以上。

Series

        Series 是 Pandas 中最基本的一维数组形式。其可以储存整数、浮点数、字符串等类型的数据。Series 基本结构如下:

pandas.Series(data=None, index=None)

        其中,data 可以是字典,或者NumPy 里的 ndarray 对象等。index 是数据索引,索引是 Pandas 数据结构中的一大特性,它主要的功能是帮助我们更快速地定位数据。

        下面,我们基于 Python 字典新建一个示例 Series。

%matplotlib inline
import pandas as pd

s = pd.Series({'a': 10, 'b': 20, 'c': 30})
s

          如上所示,该 Series 的数据值是 10, 20, 30,索引为 a, b, c,数据值的类型默认识别为 int64。你可以通过 type 来确认 s 的类型

type(s)
# pandas.core.series.Series

        由于 Pandas 基于 NumPy 开发。那么 NumPy 的数据类型 ndarray 多维数组自然就可以转换为 Pandas 中的数据。而 Series 则可以基于 NumPy 中的一维数据转换。

import numpy as np

s = pd.Series(np.random.randn(5))
s

         如上所示,我们给出了 NumPy 生成的一维随机数组,最终得到的 Series 索引默认从 0 开始,而数值类型为 float64

DataFrame

        DataFrame 是 Pandas 中最为常见、最重要且使用频率最高的数据结构。DataFrame 和平常的电子表格或 SQL 表结构相似。你可以把 DataFrame 看成是 Series 的扩展类型,它仿佛是由多个 Series 拼合而成。它和 Series 的直观区别在于,数据不但具有行索引,且具有列索引。

 来源

        DataFrame 基本结构如下:

pandas.DataFrame(data=None, index=None, columns=None)

        区别于 Series,其增加了 columns 列索引。DataFrame 可以由以下多个类型的数据构建:

  • 一维数组、列表、字典或者 Series 字典。
  • 二维或者结构化的 numpy.ndarray
  • 一个 Series 或者另一个 DataFrame

例如,我们首先使用一个由 Series 组成的字典来构建 DataFrame。

df = pd.DataFrame({'one': pd.Series([1, 2, 3]),
                   'two': pd.Series([4, 5, 6])})
df
onetwo
014
125
236

        当不指定索引时,DataFrame 的索引同样是从 0 开始。我们也可以直接通过一个列表构成的字典来生成 DataFrame。

df = pd.DataFrame({'one': [1, 2, 3],
                   'two': [4, 5, 6]})
df
onetwo
014
125
236

         或者反过来,由带字典的列表生成 DataFrame。

df = pd.DataFrame([{'one': 1, 'two': 4},
                   {'one': 2, 'two': 5},
                   {'one': 3, 'two': 6}])
df
onetwo
014
125
236

        NumPy 的多维数组非常常用,同样可以基于二维数值来构建一个 DataFrame。

pd.DataFrame(np.random.randint(5, size=(2, 4)))
0123
03214
14112

        至此,你应该已经清楚了 Pandas 常用的 Series 和 DataFrame 数据类型。Series 实际上可以被初略看出是只有 1 列数据的 DataFrame。当然,这个说法不严谨,二者的核心区别仍然是 Series 没有列索引。你可以观察如下所示由 NumPy 一维随机数组生成的 Series 和 DataFrame。

pd.Series(np.random.randint(5, size=(5,)))

  

pd.DataFrame(np.random.randint(5, size=(5,)))

        关于 Pandas 中的 Panel 等数据类型我们就不再介绍。首先是这些数据类型用的很少,其次就算你用到了,也可以通过从 DataFrame 等学到的技巧进行迁移应用,万变不离其宗。

数据读取

        我们想要使用 Pandas 来分析数据,那么首先需要读取数据。大多数情况下,数据都来源于外部的数据文件或者数据库。Pandas 提供了一系列的方法来读取外部数据,非常全面。下面,我们以最常用的 CSV 数据文件为例进行介绍。

        读取数据 CSV 文件的方法是 pandas.read_csv(),你可以直接传入一个相对路径,或者是网络 URL

df = pd.read_csv("https://labfile.oss.aliyuncs.com/courses/906/los_census.csv")
df

         由于 CSV 存储时是一个二维的表格,那么 Pandas 会自动将其读取为 DataFrame 类型。

        现在你应该就明白了,DataFrame 是 Pandas 构成的核心。一切的数据,无论是外部读取还是自行生成,我们都需要先将其转换为 Pandas 的 DataFrame 或者 Series 数据类型。实际上,大多数情况下,这一切都是设计好的,无需执行额外的转换工作。

  pd.read_ 前缀开始的方法还可以读取各式各样的数据文件,且支持连接数据库。这里,我们不再依次赘述,你可以阅读  官方文档相应章节 熟悉这些方法以及搞清楚这些方法包含的参数。

你可能又一个疑问:为什么要将数据转换为 Series 或者 DataFrame 结构?

        实际上,我现在就可以先回答这个问题。因为 Pandas 针对数据操作的全部方法都是基于 Pandas 支持的数据结构设计的。也就是说,只有 Series 或者 DataFrame 才能使用 Pandas 提供的方法和函数进行处理。所以,学习真正数据处理方法之前,我们需要将数据转换生成为 Series 或 DataFrame 类型。

基本操作

        通过上面的内容,我们已经知道一个 DataFrame 结构大致由 3 部分组成,它们分别是列名称、索引和数据。

 来源

        接下来,我们就学习针对 DataFrame 的基本操作。本次课程中,我们不会刻意强调 Series,因为你在 DataFrame 上学习的大多数方法和技巧都适用于对 Series 进行处理,二者同根同源。

上面,我们已经读取了一个外部数据,这是洛杉矶的人口普查数据。有些时候,我们读取的文件很大。如果全部输出预览这些文件,既不美观,又很耗时。还好,Pandas 提供了 head() 和 tail() 方法,它可以帮助我们只预览一小块数据。

df.head()  # 默认显示前 5 条
Zip CodeTotal PopulationMedian AgeTotal MalesTotal FemalesTotal HouseholdsAverage Household Size
091371173.50111.00
1900015711026.62846828642129714.40
2900025122325.52487626347117314.36
3900036626626.33263133635156424.22
4900046218034.83130230878225472.73
df.tail(7)  # 指定显示后 7 条
Zip CodeTotal PopulationMedian AgeTotal MalesTotal FemalesTotal HouseholdsAverage Household Size
312935507492927.53641438515208643.58
313935515079837.02505625742159633.18
314935523815828.4187111944796903.93
31593553213843.3112110178162.62
316935601891032.49491941964692.92
3179356338844.52631251032.53
31893591728530.93653363219823.67

          Pandas 还提供了统计和描述性方法,方便你从宏观的角度去了解数据集。describe() 相当于对数据集进行概览,会输出该数据集每一列数据的计数、最大值、最小值等。

df.describe()
Zip CodeTotal PopulationMedian AgeTotal MalesTotal FemalesTotal HouseholdsAverage Household Size
count319.000000319.000000319.000000319.000000319.000000319.000000319.000000
mean91000.67398133241.34169336.52758616391.56426316849.77742910964.5705332.828119
std908.36020321644.4174558.69299910747.49556610934.9864686270.6464000.835658
min90001.0000000.0000000.0000000.0000000.0000000.0000000.000000
25%90243.50000019318.50000032.4000009763.5000009633.5000006765.5000002.435000
50%90807.00000031481.00000037.10000015283.00000016202.00000010968.0000002.830000
75%91417.00000044978.00000041.00000022219.50000022690.50000014889.5000003.320000
max93591.000000105549.00000074.00000052794.00000053185.00000031087.0000004.670000

         Pandas 基于 NumPy 开发,所以任何时候你都可以通过 .values 将 DataFrame 转换为 NumPy 数组。

df.values

         这也就说明了,你可以同时使用 Pandas 和 NumPy 提供的 API 对同一数据进行操作,并在二者之间进行随意转换。这就是一个非常灵活的工具生态圈。

       除了 .values,DataFrame 支持的常见属性可以通过  官方文档相应章节 查看。其中常用的有:

df.index  # 查看索引
# RangeIndex(start=0, stop=319, step=1)
df.columns  # 查看列名

df.shape  # 查看形状
# (319, 7)

数据选择

        在数据预处理过程中,我们往往会对数据集进行切分,只将需要的某些行、列,或者数据块保留下来,输出到下一个流程中去。这也就是所谓的数据选择,或者数据索引。由于 Pandas 的数据结构中存在索引、标签,所以我们可以通过多轴索引完成对数据的选择。

基于索引选择

        当我们新建一个 DataFrame 之后,如果未自己指定行索引或者列对应的标签,那么 Pandas 会默认从 0 开始以数字的形式作为行索引,并以数据集的第一行作为列对应的标签。其实,这里的「列」也有数字索引,默认也是从 0 开始,只是未显示出来。

        所以,我们首先可以基于数字索引对数据集进行选择。这里用到的 Pandas 中的 df.iloc[:3] 方法。该方法可以接受的类型有:

  1. 整数。例如:5
  2. 整数构成的列表或数组。例如:[1, 2, 3]
  3. 布尔数组。
  4. 可返回索引值的函数或参数。

        下面,我们使用上方的示例数据进行演示。

        首先,我们可以选择前 3 行数据。这和 Python 或者 NumPy 里面的切片很相似。

df.iloc[:3]
Zip CodeTotal PopulationMedian AgeTotal MalesTotal FemalesTotal HouseholdsAverage Household Size
091371173.50111.00
1900015711026.62846828642129714.40
2900025122325.52487626347117314.36

        我们还可以选择特定的一行

df.iloc[5]

         那么选择多行,是不是 df.iloc[1, 3, 5] 这样呢?答案是错误的。df.iloc[] 的 [[行],[列]] 里面可以同时接受行和列的位置,如果你直接键入 df.iloc[1, 3, 5] 就会报错。

        所以,很简单。如果你想要选择 2,4,6 行,可以这样做。

df.iloc[[1, 3, 5]]
Zip CodeTotal PopulationMedian AgeTotal MalesTotal FemalesTotal HouseholdsAverage Household Size
1900015711026.62846828642129714.40
3900036626626.33263133635156424.22
5900053768133.91929918382150442.50

选择行学会以后,选择列就应该能想到怎么办了。例如,我们要选择第 2-4 列。

df.iloc[:, 1:4]

         这里选择 2-4 列,输入的却是 1:4。这和 Python 或者 NumPy 里面的切片操作非常相似。既然我们能定位行和列,那么只需要组合起来,我们就可以选择数据集中的任何数据了。

基于标签名称选择(重要)

        除了根据数字索引选择,还可以直接根据标签对应的名称选择。这里用到的方法和上面的 iloc 很相似,少了个 i 为 df.loc[ ]。

df.loc[] 可以接受的类型有:

  1. 单个标签。例如:2 或 'a',这里的 2 指的是标签而不是索引位置。
  2. 列表或数组包含的标签。例如:['A', 'B', 'C']
  3. 切片对象。例如:'A':'E',注意这里和上面切片的不同之处,首尾都包含在内
  4. 布尔数组。
  5. 可返回标签的函数或参数。

下面,我们来演示 df.loc[] 的用法。先选择前 3 行:

df.loc[0:2]
Zip CodeTotal PopulationMedian AgeTotal MalesTotal FemalesTotal HouseholdsAverage Household Size
091371173.50111.00
1900015711026.62846828642129714.40
2900025122325.52487626347117314.36

再选择 1,3,5 行:

df.loc[[0, 2, 4]]
Zip CodeTotal PopulationMedian AgeTotal MalesTotal FemalesTotal HouseholdsAverage Household Size
091371173.50111.00
2900025122325.52487626347117314.36
4900046218034.83130230878225472.73

 然后,选择 2-4 列:

df.loc[:, 'Total Population':'Total Males']

 最后,选择 1,3 行和 Median Age 后面的列:

df.loc[[0, 2], 'Median Age':]
Median AgeTotal MalesTotal FemalesTotal HouseholdsAverage Household Size
073.50111.00
225.52487626347117314.36

 数据删减

        虽然我们可以通过数据选择方法从一个完整的数据集中拿到我们需要的数据,但有的时候直接删除不需要的数据更加简单直接。Pandas 中,以 .drop 开头的方法都与数据删减有关。

        DataFrame.drop 可以直接去掉数据集中指定的列和行。一般在使用时,我们指定 labels 标签参数,然后再通过 axis 指定按列(axis=1)或按行(axis=0)删除即可。当然,你也可以通过索引参数删除数据,具体查看官方文档。

df.drop(labels=['Median Age', 'Total Males'], axis=1)

       DataFrame.drop_duplicates 则通常用于数据去重,即剔除数据集中的重复值。使用方法非常简单,默认情况下,它会根据所有列删除重复的行。也可以使用 subset 指定要删除的特定列上的重复项,要删除重复项并保留最后一次出现,请使用 keep='last'。

df.drop_duplicates()

注:这里输出还是319行,说明该数据集没有重复项。 

         除此之外,另一个用于数据删减的方法 DataFrame.dropna 也十分常用,其主要的用途是删除缺少值,即数据集中空缺的数据列或行。

df.dropna()

          对于提到的这 3 个常用的数据删减方法,大家一定要通过给出的链接去阅读官方文档。这些常用方法没有太多需要注意的地方,通过文档了解其用法即可,所以我们也不会化简为繁地进行介绍。

数据填充

        既然提到了数据删减,反之则可能会遇到数据填充的情况。而对于一个给定的数据集而言,我们一般不会乱填数据,而更多的是对缺失值进行填充。

        在真实的生产环境中,我们需要处理的数据文件往往没有想象中的那么美好。其中,很大几率会遇到的情况就是缺失值。缺失值主要是指数据丢失的现象,也就是数据集中的某一块数据不存在。除此之外、存在但明显不正确的数据也被归为缺失值一类。例如,在一个时间序列数据集中,某一段数据突然发生了时间流错乱,那么这一小块数据就是毫无意义的,可以被归为缺失值。

检测缺失值

        Pandas 为了更方便地检测缺失值,将不同类型数据的缺失均采用 NaN 标记。这里的 NaN 代表 Not a Number,它仅仅是作为一个标记。例外是,在时间序列里,时间戳的丢失采用 NaT 标记。

        Pandas 中用于检测缺失值主要用到两个方法,分别是:isna() 和 notna(),故名思意就是「是缺失值」和「不是缺失值」。默认会返回布尔值用于判断。

        接下来,我们人为生成一组包含缺失值的示例数据

df = pd.DataFrame(np.random.rand(9, 5), columns=list('ABCDE'))
# 插入 T 列,并打上时间戳
df.insert(value=pd.Timestamp('2017-10-1'), loc=0, column='Time')
# 将 1, 3, 5 列的 2,4,6,8 行置为缺失值
df.iloc[[1, 3, 5, 7], [0, 2, 4]] = np.nan
# 将 2, 4, 6 列的 3,5,7,9 行置为缺失值
df.iloc[[2, 4, 6, 8], [1, 3, 5]] = np.nan
df
TimeABCDE
02017-10-010.7402660.6737700.6889630.4841020.262929
1NaT0.357889NaN0.857515NaN0.533836
22017-10-01NaN0.714951NaN0.296258NaN
3NaT0.873991NaN0.732998NaN0.710549
42017-10-01NaN0.967554NaN0.470329NaN
5NaT0.551162NaN0.787744NaN0.090273
62017-10-01NaN0.205467NaN0.962078NaN
7NaT0.312581NaN0.053198NaN0.433269
82017-10-01NaN0.071785NaN0.111216NaN

 然后,通过 isna() 或 notna() 中的一个即可确定数据集中的缺失值。

df.isna()
TimeABCDE
0FalseFalseFalseFalseFalseFalse
1TrueFalseTrueFalseTrueFalse
2FalseTrueFalseTrueFalseTrue
3TrueFalseTrueFalseTrueFalse
4FalseTrueFalseTrueFalseTrue
5TrueFalseTrueFalseTrueFalse
6FalseTrueFalseTrueFalseTrue
7TrueFalseTrueFalseTrueFalse
8FalseTrueFalseTrueFalseTrue

         上面已经对缺失值的产生、检测进行了介绍。实际上,面对缺失值一般就是填充和剔除两项操作。填充和清除都是两个极端。如果你感觉有必要保留缺失值所在的列或行,那么就需要对缺失值进行填充。如果没有必要保留,就可以选择清除缺失值。

        其中,缺失值剔除的方法 dropna() 已经在上面介绍过了。下面来看一看填充缺失值 fillna() 方法。        

首先,我们可以用相同的标量值替换 NaN,比如用 0

df.fillna(0)
TimeABCDE
02017-10-01 00:00:000.7402660.6737700.6889630.4841020.262929
100.3578890.0000000.8575150.0000000.533836
22017-10-01 00:00:000.0000000.7149510.0000000.2962580.000000
300.8739910.0000000.7329980.0000000.710549
42017-10-01 00:00:000.0000000.9675540.0000000.4703290.000000
500.5511620.0000000.7877440.0000000.090273
62017-10-01 00:00:000.0000000.2054670.0000000.9620780.000000
700.3125810.0000000.0531980.0000000.433269
82017-10-01 00:00:000.0000000.0717850.0000000.1112160.000000

         除了直接填充值,我们还可以通过参数,将缺失值前面或者后面的值填充给相应的缺失值。①使用缺失值前面的值进行填充:

df.fillna(method='pad')
TimeABCDE
02017-10-010.7402660.6737700.6889630.4841020.262929
12017-10-010.3578890.6737700.8575150.4841020.533836
22017-10-010.3578890.7149510.8575150.2962580.533836
32017-10-010.8739910.7149510.7329980.2962580.710549
42017-10-010.8739910.9675540.7329980.4703290.710549
52017-10-010.5511620.9675540.7877440.4703290.090273
62017-10-010.5511620.2054670.7877440.9620780.090273
72017-10-010.3125810.2054670.0531980.9620780.433269
82017-10-010.3125810.0717850.0531980.1112160.433269

 ②使用缺失值后面的值

df.fillna(method='bfill')
TimeABCDE
02017-10-010.7402660.6737700.6889630.4841020.262929
12017-10-010.3578890.7149510.8575150.2962580.533836
22017-10-010.8739910.7149510.7329980.2962580.710549
32017-10-010.8739910.9675540.7329980.4703290.710549
42017-10-010.5511620.9675540.7877440.4703290.090273
52017-10-010.5511620.2054670.7877440.9620780.090273
62017-10-010.3125810.2054670.0531980.9620780.433269
72017-10-010.3125810.0717850.0531980.1112160.433269
82017-10-01NaN0.071785NaN0.111216NaN

         最后一行由于没有对于的后序值,自然继续存在缺失值。

        上面的例子中,我们的缺失值是间隔存在的。那么,如果存在连续的缺失值是怎样的情况呢?试一试。首先,我们将数据集的第 2,4 ,6 列的第 3,5 行也置为缺失值。

df.iloc[[3, 5], [1, 3, 5]] = np.nan

然后来正向填充:

df.fillna(method='pad')
TimeABCDE
02017-10-010.7402660.6737700.6889630.4841020.262929
12017-10-010.3578890.6737700.8575150.4841020.533836
22017-10-010.3578890.7149510.8575150.2962580.533836
32017-10-010.3578890.7149510.8575150.2962580.533836
42017-10-010.3578890.9675540.8575150.4703290.533836
52017-10-010.3578890.9675540.8575150.4703290.533836
62017-10-010.3578890.2054670.8575150.9620780.533836
72017-10-010.3125810.2054670.0531980.9620780.433269
82017-10-010.3125810.0717850.0531980.1112160.433269

         可以看到,连续缺失值也是按照前序数值进行填充的,并且完全填充。这里,我们可以通过 limit= 参数设置连续填充的限制数量

df.fillna(method='pad', limit=1)  # 最多填充一项
TimeABCDE
02017-10-010.7402660.6737700.6889630.4841020.262929
12017-10-010.3578890.6737700.8575150.4841020.533836
22017-10-010.3578890.7149510.8575150.2962580.533836
32017-10-01NaN0.714951NaN0.296258NaN
42017-10-01NaN0.967554NaN0.470329NaN
52017-10-01NaN0.967554NaN0.470329NaN
62017-10-01NaN0.205467NaN0.962078NaN
72017-10-010.3125810.2054670.0531980.9620780.433269
82017-10-010.3125810.0717850.0531980.1112160.433269

         除了上面的填充方式,还可以通过 Pandas 自带的求平均值方法等来填充特定列或行。举个例子:

df.fillna(df.mean()['C':'E'])
TimeABCDE
02017-10-010.7402660.6737700.6889630.4841020.262929
1NaT0.357889NaN0.8575150.4647970.533836
22017-10-01NaN0.7149510.5332250.2962580.410011
3NaTNaNNaN0.5332250.4647970.410011
42017-10-01NaN0.9675540.5332250.4703290.410011
5NaTNaNNaN0.5332250.4647970.410011
62017-10-01NaN0.2054670.5332250.9620780.410011
7NaT0.312581NaN0.0531980.4647970.433269
82017-10-01NaN0.0717850.5332250.1112160.410011

         对 C 列到 E 列用平均值填充。

插值填充

        插值是数值分析中一种方法。简而言之,就是借助于一个函数(线性或非线性),再根据已知数据去求解未知数据的值。插值在数据领域非常常见,它的好处在于,可以尽量去还原数据本身的样子。

我们可以通过 interpolate() 方法完成线性插值。当然,其他一些插值算法可以阅读官方文档了解。

# 生成一个 DataFrame
df = pd.DataFrame({'A': [1.1, 2.2, np.nan, 4.5, 5.7, 6.9],
                   'B': [.21, np.nan, np.nan, 3.1, 11.7, 13.2]})
df

        对于上面存在的缺失值,如果通过前后值,或者平均值来填充是不太能反映出趋势的。这时候,插值最好使。我们用默认的线性插值试一试。

df_interpolate = df.interpolate()
df_interpolate
AB
01.100.210000
12.201.173333
23.352.136667
34.503.100000
45.7011.700000
56.9013.200000

         下图展示了插值后的数据,明显看出插值结果符合数据的变化趋势。如果按照前后数据顺序填充,则无法做到这一点。

对于 interpolate() 支持的插值算法,也就是 method=。下面给出几条选择的建议:

  1. 如果你的数据增长速率越来越快,可以选择 method='quadratic'二次插值
  2. 如果数据集呈现出累计分布的样子,推荐选择 method='pchip'
  3. 如果需要填补缺失值,以平滑绘图为目标,推荐选择 method='akima'

当然,最后提到的 method='akima',需要你的环境中安装了 Scipy 库。除此之外,method='barycentric' 和 method='pchip' 同样也需要 Scipy 才能使用。

数据可视化

        NumPy,Pandas,Matplotlib 构成了一个完善的数据分析生态圈,所以 3 个工具的兼容性也非常好,甚至共享了大量的接口。当我们的数据是以 DataFrame 格式呈现时,可以直接使用 Pandas 提供的 DataFrame.plot 方法调用 Matplotlib 接口绘制常见的图形。

例如,我们使用上面插值后的数据 df_interpolate 绘制线形图。

df_interpolate.plot()

         其他样式的图形也很简单,指定 kind= 参数即可。

df_interpolate.plot(kind='bar')

         更多的图形样式和参数,阅读官方文档中的详细说明。Pandas 绘图虽然不可能做到 Matplotlib 的灵活性,但是其简单易用,适合于数据的快速呈现和预览。

其他用法

        由于 Pandas 包含的内容实在太多,除了阅读完整的官方文档,很难做到通过一个实验或者一个课程进行全面了解。当然,本课程的目的是带大家熟悉 Pandas 的常用基础方法,至少你大致清楚了 Pandas 是什么,能干什么。

除了上面提到的一些方法和技巧,实际上 Pandas 常用的还有:

  •  数据计算,例如:DataFrame.add 等。
  •  数据聚合,例如:DataFrame.groupby 等。
  •  统计分析,例如:DataFrame.abs 等。
  •  时间序列,例如:DataFrame.shift 等。

        更多关于pandas的知识,可以关注我后续的文章,感谢你的大力支持!!! 

实验总结

        本次实验,我们着重介绍了 Pandas 的数据结构,你需要对 Series 和 DataFrame 有深入的认识,才能对后面采用 Pandas 进行数据预处理有更深刻的理解。除此之外,我们了解了 Pandas 数据读取、数据选择、数据删减、数据填充的方法和技巧,希望大家后续结合官方文档进一步深入理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/10042.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

有效的括号(力扣刷题)代码随想录刷题

给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相同类型的左…

RK3568平台开发系列讲解(驱动基础篇)mmap系统调用详解

🚀返回专栏总目录 文章目录 一、什么是mmap二、mmap映射类型2.1、私有匿名映射2.2、私有文件映射2.3、共享文件映射2.4、共享匿名映射沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本文将详细介绍mmap系统调用。 一、什么是mmap mmap/munmap函数是用户空间中常用的…

Nacos 性能报告

目录 一、测试目的 二、测试工具 三、测试环境 1. 环境 服务端 客户端 2. 启动参数 服务端 客户端 四、测试场景 1. 大规模服务注册后达到稳定状态 场景描述 2. 大规模服务注册达到稳定状态后,部分实例频繁发布 场景描述 五、测试数据 1. 大规模服务…

软件测试基础

软件测试的定义、软件测试的目的 IEEE:The process of running or testing the system manually or automatically by using tools, in order to verify whether it satisfies the requirements or to make clear the differences between the actual outcome and…

DDoS攻击实验笔记

DoS&DDoS简介 DoS(Denial of Service),拒绝服务攻击是通过一些方法影响服务的可用性,比如早期主要基于系统和应用程序的漏洞,只需要几个请求或数据包就能导致长时间的服务不可用,但易被入侵检测系统发现。 DDoS(Distributed D…

日撸 Java 三百行day28-30

文章目录说明day28-30 Huffman 编码 (节点定义与文件读取)1.建树过程(以图为例)2.哈夫曼树特点3.分析代码过程3.1 抽象成员变量3.2结合文章梳理思路1.读文本2.解析文本内容:3.建树4.生成哈夫曼编码5.编码6.解码4.其他4.1 java 类型强转4.2 ja…

linux线程调度策略

系统中既有分时调度,又有时间片轮转调度和先进先出调度 学习这个主要为了在linux多线程中,解决几条指令间延时在1-2ms内; 1.比如之前处理过:给一个板子发送一个can指令,接着需要给另外一个模块发送移动指令&#xff0c…

用ChatGPT怎么赚钱?普通人用这5个方法也能赚到生活费

ChatGPT在互联网火得一塌糊涂,因为它可以帮很多人解决问题。比如:帮编辑人员写文章,还可以替代程序员写代码,帮策划人员写文案策划等等。ChatGPT这么厉害,能否用它来赚钱呢?今天和大家分享用ChatGPT赚钱的5…

关键词数据分析-搜索词和关键词分析工具

要搜索热门关键词获取,可以采用以下几种方法: 使用百度指数:百度指数是一个实用的工具,可用于查看关键词的热度趋势、搜索量等数据。在百度指数中,您可以输入您要搜索的关键词,并查看近期的相关数据。这可以…

短视频矩阵怎么玩?抖音短视频矩阵运营详细攻略!

短视频矩阵的工作包括确定目标受众和平台、制定短视频内容策、短视频制作与发布,私信评论维护,短视频数据分析等。传统短视频矩阵需要大量的人力物力,操作起来比较复杂,使用短视频矩阵工具则可以提供极大的便利。      1、确定…

Vue项目中关于全局css的处理

Vue项目中关于全局css的处理步骤一:定义声明全局CSS的样式文件(common.scss)步骤二:挂载到全局封装一:对common.scss拆分封装二:新建index.scss,对elementPlus或者element-ui样式进行覆盖封装三:variable.s…

GitLab CI/CD 新书发布,助企业降本增效

前言 大家好,我是CSDN的拿我格子衫来, 昨天我的第一本书《GitLab CI/CD 从入门到实战》上架啦,这是业内第一本详细讲解GitLab CI/CD的书籍。 历经无数个日夜,最终开花结果。感触良多,今天就借这篇文章来谈一谈这本书的…

Java基础(十五):异常处理

Java基础系列文章 Java基础(一):语言概述 Java基础(二):原码、反码、补码及进制之间的运算 Java基础(三):数据类型与进制 Java基础(四):逻辑运算符和位运算符 Java基础(五):流程控制语句 Java基础(六)&#xff1…

Linux内核设备驱动设备树概念与使用

一、设备树概念以及作用 1.1设备树概念 设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(DeviceTree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比…

python入门:cl.exe‘ failed with exit status 2错误通用解决方案

文章目录 错误一错误二pypi.org独立安装正确安装错误一 error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/ 这个错误在windows系统上安装python工…

Spring《三》DI依赖注入

🍎道阻且长,行则将至。🍓 上一篇:Spring《二》bean的实例化与生命周期 下一篇:敬请期待 目录一、setter注入🍉1.注入引用数据类型2.注入简单数据类型二、构造器注入🍊1.注入引用数据类型2.简单数…

Spring 源码分析(二)——GenericBeanDefinition 分析

BeanDefinition 中存储着 Bean 的定义信息,它具有属性值、构造函数参数值以及具体实现 Bean 提供的进一步信息,在学习 Spring 的 Bean 初始化流程之前,还是非常有必要先了解一下 BeanDefinition。 一、注册 Bean 示例 首先,本文…

SpringCloud微服务技术栈之网关服务Gateway

文章目录SpringCloud微服务技术栈之网关服务Gateway前言网关服务Gateway的基本概念Gateway的体系结构Gateway的主要功能网关服务Gateway的架构设计架构设计方案示例代码网关服务Gateway的实践操作1. 创建工程2. 配置路由规则3. 实现过滤器4. 集成服务注册中心5. 启动网关服务器…

2020年11月信息系统项目管理师真题(综合+案例)

请点击↑关注、收藏,本博客免费为你获取精彩知识分享!有惊喜哟!! 1、( )使系统的描述及信息模型的表示与客观实体相对应,符合人们的思维习惯,有利于系统开发过程中用户与开发人员的…

Redhat6.7离线安装rabbitmq

一、下载资源文件(.rpm文件) 链接: https://pan.baidu.com/s/1j2Ze_Jjm0oMrP-r95PPCtA?pwdv3is 提取码: v3is 复制这段内容后打开百度网盘手机App,操作更方便哦 创建rabbit文件夹Mkdir rabbit 三、通过ftp上传文件 四、安装erlang环境 …