四、大数据深入浅出之python pandas(十四万字长文《下》)

您所在的位置:网站首页 dataframe数据结构的属性 四、大数据深入浅出之python pandas(十四万字长文《下》)

四、大数据深入浅出之python pandas(十四万字长文《下》)

#四、大数据深入浅出之python pandas(十四万字长文《下》)| 来源: 网络整理| 查看: 265

十五、pandas统计函数

Pandas 的本质是统计学原理在计算机领域的一种应用实现,通过编程的方式达到分析、描述数据的目的。而统计函数则是统计学中用于计算和分析数据的一种工具。在数据分析的过程中,使用统计函数有助于我们理解和分析数据。本节将学习几个常见的统计函数,比如百分比函数、协方差函数、相关系数等。

百分比变化(pct_change)

Series 和 DatFrames 都可以使用 pct_change() 函数。该函数将每个元素与其前一个元素进行比较,并计算前后数值的百分比变化。示例如下:

import pandas as pd

import numpy as np

#Series结构

s = pd.Series([1,2,3,4,5,4])

print (s.pct_change())

#DataFrame

df = pd.DataFrame(np.random.randn(5, 2))

print(df.pct_change())

输出结果:

10 NaN

21 1.000000

32 0.500000

43 0.333333

54 0.250000

65 -0.200000

7dtype: float64

8 0 1

90 NaN NaN

101 74.779242 0.624260

112 -0.353652 -1.104352

123 -2.422813 -13.994103

134 -3.828316 -1.853092

默认情况下,pct_change() 对列进行操作,如果想要操作行,则需要传递参数 axis=1 参数。示例如下:

import pandas as pd

import numpy as np

#DataFrame

df = pd.DataFrame(np.random.randn(3, 2))

print(df.pct_change(axis=1))

输出结果:

1 0 1

20 NaN 3.035670

31 NaN -0.318259

42 NaN 0.227580

协方差(cov)

Series 对象提供了一个cov方法用来计算 Series 对象之间的协方差。同时,该方法也会将缺失值(NAN )自动排除。

示例如下:

import pandas as pd

import numpy as np

s1 = pd.Series(np.random.randn(10))

s2 = pd.Series(np.random.randn(10))

print (s1.cov(s2))

输出结果:

10.20789380904226645

当应用于 DataFrame 时,协方差(cov)将计算所有列之间的协方差。

import pandas as pd

import numpy as np

frame = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e'])

#计算a与b之间的协方差值

print (frame['a'].cov(frame['b']))

#计算所有数列的协方差值

print (frame.cov())

输出结果:

1-0.37822395480394827

2 a b c d e

3a 1.643529 -0.378224 0.181642 0.049969 -0.113700

4b -0.378224 1.561760 -0.054868 0.144664 -0.231134

5c 0.181642 -0.054868 0.628367 -0.125703 0.324442

6d 0.049969 0.144664 -0.125703 0.480301 -0.388879

7e -0.113700 -0.231134 0.324442 -0.388879 0.848377

相关系数(corr)

相关系数显示任意两个 Series 之间的线性关系。Pandas 提供了计算相关性的三种方法,分别是 pearson(default)、spearman() 和 kendall()。

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(10, 5), columns=['a', 'b', 'c', 'd', 'e'])

print (df['b'].corr(frame['c']))

print (df.corr())

输出结果:

10.5540831507407936

2 a b c d e

3a 1.000000 -0.500903 -0.058497 -0.767226 0.218416

4b -0.500903 1.000000 -0.091239 0.805388 -0.020172

5c -0.058497 -0.091239 1.000000 0.115905 0.083969

6d -0.767226 0.805388 0.115905 1.000000 0.015028

7e 0.218416 -0.020172 0.083969 0.015028 1.000000

注意:如果 DataFrame 存在非数值(NAN),该方法会自动将其删除。

排名(rank)

rank() 按照某种规则(升序或者降序)对序列中的元素值排名,该函数的返回值的也是一个序列,包含了原序列中每个元素值的名次。如果序列中包含两个相同的的元素值,那么会为其分配两者的平均排名。示例如下:

import pandas as pd

import numpy as np

#返回5个随机值,然后使用rank对其排名

s = pd.Series(np.random.randn(5), index=list('abcde'))

s['d'] = s['b']

print(s)

#a/b排名分别为2和3,其平均排名为2.5

print(s.rank())

输出结果:

1a -0.689585

2b -0.545871

3c 0.148264

4d -0.545871

5e -0.205043

6dtype: float64

7

8排名后输出:

9a 1.0

10b 2.5

11c 5.0

12d 2.5

13e 4.0

14dtype: float64

method参数

rank() 提供了 method 参数,可以针对相同数据,进行不同方式的排名。如下所示:

average:默认值,如果数据相同则分配平均排名;min:给相同数据分配最低排名;max:给相同数据分配最大排名;first:对于相同数据,根据出现在数组中的顺序进行排名。2) aisx&ascening

rank() 有一个ascening参数, 默认为 True 代表升序;如果为 False,则表示降序排名(将较大的数值分配给较小的排名)。

rank() 默认按行方向排名(axis=0),也可以更改为 axis =1,按列排名。示例如下:

import pandas as pd

import numpy as np

a = pd.DataFrame(np.arange(12).reshape(3,4),columns = list("abdc"))

a =a.sort_index(axis=1,ascending=False)

a.iloc[[1,1],[1,2]] = 6

#按行排名,将相同数值设置为所在行数值的最大排名

print(a.rank(axis=1,method="max"))

输出结果:

1 d c b a

20 3.0 4.0 2.0 1.0

31 4.0 4.0 4.0 1.0

42 3.0 4.0 2.0 1.0

与 method="min"进行对比,如下所示:

import pandas as pd

import numpy as np

a = pd.DataFrame(np.arange(12).reshape(3,4),columns = list("abdc"))

a =a.sort_index(axis=1,ascending=False)

a.iloc[[1,1],[1,2]] = 6

#按行排名,将相同数值设置为所在行数值的最小排名

print(a.rank(axis=1,method="min"))

输出结果:

1 d c b a

20 3.0 4.0 2.0 1.0

31 2.0 2.0 2.0 1.0

42 3.0 4.0 2.0 1.0

十六、pandas窗口函数

为了能更好地处理数值型数据,Pandas 提供了几种窗口函数,比如移动函数(rolling)、扩展函数(expanding)和指数加权函数(ewm)。

窗口函数应用场景非常多。举一个简单的例子:现在有 10 天的销售额,而您想每 3 天求一次销售总和,也就说第五天的销售额等于(第三天 + 第四天 + 第五天)的销售额之和,此时窗口函数就派上用场了。

窗口是一种形象化的叫法,这些函数在执行操作时,就如同窗口一样在数据区间上移动。

本节学习主要讲解如何在 DataFrame 和 Series 对象上应用窗口函数。

rolling()

rolling() 又称移动窗口函数,它可以与 mean、count、sum、median、std 等聚合函数一起使用。为了使用方便,Pandas 为移动函数定义了专门的方法聚合方法,比如 rolling_mean()、rolling_count()、rolling_sum() 等。其的语法格式如下:

1rolling(window=n, min_periods=None, center=False)

常用参数说明如下:

参数名称说明window默认值为 1,表示窗口的大小,也就是观测值的数量,min_periods表示窗口的最小观察值,默认与 window 的参数值相等。center是否把中间值做为窗口标准,默认值为 False。

下面看一组示例:

import pandas as pd

import numpy as np

#生成时间序列

df = pd.DataFrame(np.random.randn(8, 4),index = pd.date_range('12/1/2020', periods=8),columns = ['A', 'B', 'C', 'D'])

print(df)

#每3个数求求一次均值

print(df.rolling(window=3).mean())

输出结果:

1 A B C D

22020-12-01 0.580058 -0.715246 0.440427 -1.106783

32020-12-02 -1.313982 0.068954 -0.906665 1.382941

42020-12-03 0.349844 -0.549509 -0.806577 0.261794

52020-12-04 -0.497054 0.921995 0.232008 -0.815291

62020-12-05 2.658108 0.447783 0.049340 0.329209

72020-12-06 -0.271670 -0.070299 0.860684 -0.095122

82020-12-07 -0.706780 -0.949392 0.679680 0.230930

92020-12-08 0.027379 -0.056543 -1.067625 1.386399

10

11 A B C D

122020-12-01 NaN NaN NaN NaN

132020-12-02 NaN NaN NaN NaN

142020-12-03 -0.128027 -0.398600 -0.424272 0.179317

152020-12-04 -0.487064 0.147147 -0.493745 0.276481

162020-12-05 0.836966 0.273423 -0.175076 -0.074763

172020-12-06 0.629794 0.433160 0.380677 -0.193734

182020-12-07 0.559886 -0.190636 0.529901 0.155006

192020-12-08 -0.317024 -0.358745 0.157580 0.507402

window=3表示是每一列中依次紧邻的每 3 个数求一次均值。当不满足 3 个数时,所求值均为 NaN 值,因此前两列的值为 NaN,直到第三行值才满足要求 window =3。求均值的公式如下所示:

(index1+index2+index3)/3

expanding()

expanding() 又叫扩展窗口函数,扩展是指由序列的第一个元素开始,逐个向后计算元素的聚合值。

下面示例,min_periods = n表示向后移动 n 个值计求一次平均值:

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),

index = pd.date_range('1/1/2018', periods=10),

columns = ['A', 'B', 'C', 'D'])

print (df.expanding(min_periods=3).mean())

输出结果:

1 A B C D

22020-01-01 NaN NaN NaN NaN

32020-01-02 NaN NaN NaN NaN

42020-01-03 -0.567833 0.258723 0.498782 0.403639

52020-01-04 -0.384198 -0.093490 0.456058 0.459122

62020-01-05 -0.193821 0.085318 0.389533 0.552429

72020-01-06 -0.113941 0.252397 0.214789 0.455281

82020-01-07 0.147863 0.400141 -0.062493 0.565990

92020-01-08 -0.036038 0.452132 -0.091939 0.371364

102020-01-09 -0.043203 0.368912 -0.033141 0.328143

112020-01-10 -0.100571 0.349378 -0.078225 0.225649

设置 min_periods=3,表示至少 3 个数求一次均值,计算方式为 (index0+index1+index2)/3,而 index3 的计算方式是 (index0+index1+index2+index3)/3,依次类推。

ewm()

ewm(全称 Exponentially Weighted Moving)表示指数加权移动。ewn() 函数先会对序列元素做指数加权运算,其次计算加权后的均值。该函数通过指定 com、span 或者 halflife 参数来实现指数加权移动。示例如下:

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(10, 4),

index = pd.date_range('12/1/2020', periods=10),

columns = ['A', 'B', 'C', 'D'])

#设置com=0.5,先加权再求均值

print(df.ewm(com=0.5).mean())

输出结果:

1 A B C D

22020-12-01 -1.511428 1.427826 0.252652 0.093601

32020-12-02 -1.245101 -0.118346 0.170232 -0.207065

42020-12-03 0.131456 -0.271979 -0.679315 -0.589689

52020-12-04 -0.835228 0.094073 -0.973924 -0.081684

62020-12-05 1.279812 1.099368 0.203033 0.019014

72020-12-06 0.132027 -0.625744 -0.145090 -0.318155

82020-12-07 0.820230 0.371620 0.119683 -0.227101

92020-12-08 1.088283 -0.275570 0.358557 -1.050606

102020-12-09 0.538304 -1.288146 0.590358 -0.164057

112020-12-10 0.589177 -1.514472 -0.613158 0.367322

在数据分析的过程中,使用窗口函数能够提升数据的准确性,并且使数据曲线的变化趋势更加平滑,从而让数据分析变得更加准确、可靠

十七、应用聚合函数

首先让我们创建一个 DataFrame 对象,然后对聚合函数进行应用。

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(5, 4),index = pd.date_range('12/14/2020', periods=5),columns = ['A', 'B', 'C', 'D'])

print (df)

#窗口大小为3,min_periods 最小观测值为1

r = df.rolling(window=3,min_periods=1)

print(r)

输出结果:

1 A B C D

22020-12-14 0.941621 1.205489 0.473771 -0.348169

32020-12-15 -0.276954 0.076387 0.104194 1.537357

42020-12-16 0.582515 0.481999 -0.652332 -1.893678

52020-12-17 -0.286432 0.923514 0.285255 -0.739378

62020-12-18 2.063422 -0.465873 -0.946809 1.590234

7

8Rolling [window=3,min_periods=1,center=False,axis=0]

对整体聚合您可以把一个聚合函数传递给 DataFrame,示例如下:import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.randn(5, 4),index = pd.date_range('12/14/2020', periods=5),columns = ['A', 'B', 'C', 'D'])print (df)#窗口大小为3,min_periods 最小观测值为1r = df.rolling(window=3,min_periods=1)#使用 aggregate()聚合操作print(r.aggregate(np.sum))输出结果:1 A B C D22020-12-14 0.133713 0.746781 0.499385 0.58979932020-12-15 -0.777572 0.531269 0.600577 -0.39362342020-12-16 0.408115 -0.874079 0.584320 0.50758052020-12-17 -1.033055 -1.185399 -0.546567 2.09464362020-12-18 0.469394 -1.110549 -0.856245 0.26082778 A B C D92020-12-14 0.133713 0.746781 0.499385 0.589799102020-12-15 -0.643859 1.278050 1.099962 0.196176112020-12-16 -0.235744 0.403971 1.684281 0.703756122020-12-17 -1.402513 -1.528209 0.638330 2.208601132020-12-18 -0.155546 -3.170027 -0.818492 2.863051对任意某一列聚合import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.randn(5, 4),index = pd.date_range('12/14/2020', periods=5),columns = ['A', 'B', 'C', 'D'])#窗口大小为3,min_periods 最小观测值为1r = df.rolling(window=3,min_periods=1)#对 A 列聚合print(r['A'].aggregate(np.sum))输出结果:12020-12-14 1.05150122020-12-15 1.35457432020-12-16 0.89633542020-12-17 0.50847052020-12-18 2.3337326Freq: D, Name: A, dtype: float64对多列数据聚合import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.randn(5, 4),index = pd.date_range('12/14/2020', periods=5),columns = ['A', 'B', 'C', 'D'])#窗口大小为3,min_periods 最小观测值为1r = df.rolling(window=3,min_periods=1)#对 A/B 两列聚合print(r['A','B'].aggregate(np.sum))输出结果:1 A B22020-12-14 0.639867 -0.22999032020-12-15 0.352028 0.25791842020-12-16 0.637845 2.64362852020-12-17 0.432715 2.42860462020-12-18 -1.575766 0.969600对单列应用多个函数import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.randn(5, 4),index = pd.date_range('12/14/2020', periods=5),columns = ['A', 'B', 'C', 'D'])#窗口大小为3,min_periods 最小观测值为1r = df.rolling(window=3,min_periods=1)#对 A/B 两列聚合print(r['A','B'].aggregate([np.sum,np.mean]))输出结果:1 sum mean22020-12-14 -0.469643 -0.46964332020-12-15 -0.626856 -0.31342842020-12-16 -1.820226 -0.60674252020-12-17 -2.007323 -0.66910862020-12-18 -0.595736 -0.198579对不同列应用多个函数import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.randn(5, 4), index = pd.date_range('12/11/2020', periods=5), columns = ['A', 'B', 'C', 'D'])r = df.rolling(window=3,min_periods=1)print( r['A','B'].aggregate([np.sum,np.mean]))输出结果:1 A B2 sum mean sum mean32020-12-14 -1.428882 -1.428882 -0.417241 -0.41724142020-12-15 -1.315151 -0.657576 -1.580616 -0.79030852020-12-16 -2.093907 -0.697969 -2.260181 -0.75339462020-12-17 -1.324490 -0.441497 -1.578467 -0.52615672020-12-18 -2.400948 -0.800316 -0.452740 -0.150913对不同列应用不同函数

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(3, 4),

index = pd.date_range('12/14/2020', periods=3),

columns = ['A', 'B', 'C', 'D'])

r = df.rolling(window=3,min_periods=1)

print(r.aggregate({'A': np.sum,'B': np.mean}))

输出结果:

1 A B

22020-12-14 0.503535 -1.301423

32020-12-15 0.170056 -0.550289

42020-12-16 -0.086081 -0.140532

十八、pandas缺失值处理

在一些数据分析业务中,数据缺失是我们经常遇见的问题,缺失值会导致数据质量的下降,从而影响模型预测的准确性,这对于机器学习和数据挖掘影响尤为严重。因此妥善的处理缺失值能够使模型预测更为准确和有效。

为什么会存在缺失值?

前面章节的示例中,我们遇到过很多 NaN 值,关于缺失值您可能会有很多疑问,数据为什么会丢失数据呢,又是从什么时候丢失的呢?通过下面场景,您会得到答案。

其实在很多时候,人们往往不愿意过多透露自己的信息。假如您正在对用户的产品体验做调查,在这个过程中您会发现,一些用户很乐意分享自己使用产品的体验,但他是不愿意透露自己的姓名和联系方式;还有一些用户愿意分享他们使用产品的全部经过,包括自己的姓名和联系方式。因此,总有一些数据会因为某些不可抗力的因素丢失,这种情况在现实生活中会经常遇到。

什么是稀疏数据?

稀疏数据,指的是在数据库或者数据集中存在大量缺失数据或者空值,我们把这样的数据集称为稀疏数据集。稀疏数据不是无效数据,只不过是信息不全而已,只要通过适当的方法就可以“变废为宝”。

稀疏数据的来源与产生原因有很多种,大致归为以下几种:

由于调查不当产生的稀疏数据;由于天然限制产生的稀疏数据;文本挖掘中产生的稀疏数据。缺失值处理

那么 Pandas 是如何处理缺失值的呢,下面让我们一起看一下。

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f','h'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print(df)

输出结果:

1 0 1 2

2a 0.187208 -0.951407 0.316340

3b NaN NaN NaN

4c -0.365741 -1.983977 -1.052170

5d NaN NaN NaN

6e -1.024180 1.550515 0.317156

7f -0.799921 -0.686590 1.383229

8g NaN NaN NaN

9h -0.207958 0.426733 -0.325951

上述示例,通过使用 reindex(重构索引),我们创建了一个存在缺少值的 DataFrame 对象。

检查缺失值

为了使检测缺失值变得更容易,Pandas 提供了 isnull() 和 notnull() 两个函数,它们同时适用于 Series 和 DataFrame 对象。

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f','h'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print(df['noe'].isnull())

输出结果:

1a False

2b True

3c False

4d True

5e False

6f False

7g True

8h False

9Name: 1, dtype: bool

notnull() 函数,使用示例:

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f','h'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print df['one'].notnull()

输出结果:

1a True

2b False

3c True

4d False

5e True

6f True

7g False

8h True

9Name: 1, dtype: bool

缺失数据计算

计算缺失数据时,需要注意两点:首先数据求和时,将 NA 值视为 0 ,其次,如果要计算的数据为 NA,那么结果就是 NA。示例如下:

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f','h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print (df['one'].sum())

print()

输出结果:

13.4516595395128

清理并填充缺失值

Pandas 提供了多种方法来清除缺失值。fillna() 函数可以实现用非空数据“填充”NaN 值。

用标量值替换NaN值下列程序将 NaN 值 替换为了 0,如下所示:import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.randn(3, 3), index=['a', 'c', 'e'],columns=['one','two', 'three'])df = df.reindex(['a', 'b', 'c'])print(df)#用 0 填充 NaNprint (df.fillna(0))输出结果:1 one two three2a 1.497185 -0.703897 -0.0505133b NaN NaN NaN4c 2.008315 1.342690 -0.25585556 one two three7a 1.497185 -0.703897 -0.0505138b 0.000000 0.000000 0.0000009c 2.008315 1.342690 -0.255855当然根据您自己的需求,您也可以用其他值进行填充。向前和向后填充NAimport pandas as pdimport numpy as npdf = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f','h'],columns=['one', 'two', 'three'])df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])print df.fillna(method='ffill')输出结果:1 one two three2a 0.871741 0.311057 0.0910053b 0.871741 0.311057 0.0910054c 0.107345 -0.662864 0.8267165d 0.107345 -0.662864 0.8267166e 1.630221 0.482504 -0.7287677f 1.283206 -0.145178 0.1091558g 1.283206 -0.145178 0.1091559h 0.222176 0.886768 0.347820或者您也可以采用向后填充的方法。使用replace替换通用值

在某些情况下,您需要使用 replace() 将 DataFrame 中的通用值替换成特定值,这和使用 fillna() 函数替换 NaN 值是类似的。示例如下:

import pandas as pd

import numpy as np

df = pd.DataFrame({'one':[10,20,30,40,50,666], 'two':[99,0,30,40,50,60]})

#使用replace()方法

print (df.replace({99:10,666:60,0:20}))

删除缺失值

如果想删除缺失值,那么使用 dropna() 函数与参数 axis 可以实现。在默认情况下,按照 axis=0 来按行处理,这意味着如果某一行中存在 NaN 值将会删除整行数据。示例如下:

import pandas as pd

import numpy as np

df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'e', 'f','h'],columns=['one', 'two', 'three'])

df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])

print(df)

#删除缺失值

print (df.dropna())

输出结果:

1 one two three

2a -2.025435 0.617616 0.862096

3b NaN NaN NaN

4c -1.710705 1.780539 -2.313227

5d NaN NaN NaN

6e -2.347188 -0.498857 -1.070605

7f -0.159588 1.205773 -0.046752

8g NaN NaN NaN

9h -0.549372 -1.740350 0.444356

10

11 one two three

12a -2.025435 0.617616 0.862096

13c -1.710705 1.780539 -2.313227

14e -2.347188 -0.498857 -1.070605

15f -0.159588 1.205773 -0.046752

16h -0.549372 -1.740350 0.444356

axis = 1 表示按列处理,处理结果是一个空的 DataFrame 对象。

十九、pandas分组操作

在数据分析中,经常会遇到这样的情况:根据某一列(或多列)标签把数据划分为不同的组别,然后再对其进行数据分析。比如,某网站对注册用户的性别或者年龄等进行分组,从而研究出网站用户的画像(特点)。在 Pandas 中,要完成数据的分组操作,需要使用 groupby() 函数,它和 SQL 的GROUP BY操作非常相似。

在划分出来的组(group)上应用一些统计函数,从而达到数据分析的目的,比如对分组数据进行聚合、转换,或者过滤。这个过程主要包含以下三步:

拆分(Spliting):表示对数据进行分组;应用(Applying):对分组数据应用聚合函数,进行相应计算;合并(Combining):最后汇总计算结果。

下面对 groupby() 函数的应用过程进行具体的讲解。

创建DataFrame对象

首先我们创建一个 DataFrame 对象,下面数据描述了某班学生,计算机选修课的考试成绩:

import pandas as pd

import numpy as np

data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],

'score': [82, 98, 91, 87],

'option_course': ['C#','Python','Java','C']}

df = pd.DataFrame(data)

print(df)

输出结果:

1 Name score option_course

20 John 82 C#

31 Helen 98 Python

42 Sona 91 Java

53 Ella 87 C

创建groupby分组对象

使用 groupby() 可以沿着任意轴分组。您可以把分组时指定的键(key)作为每组的组名,方法如下所示:

df.groupby("key")df.groupby("key",axis=1)df.groupby(["key1","key2"])

通过上述方法对 DataFrame 对象进行分组操作:

import pandas as pd

import numpy as np

data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],

'score': [82, 98, 91, 87],

'option_course': ['C#','Python','Java','C']}

df = pd.DataFrame(data)

print(df)

#生成分组groupby对象

print(df.groupby('score'))

输出结果:

1

查看分组结果groups查看分组结果通过调用groups属性查看分组结果:import pandas as pdimport numpy as npdata = {'Name': ['John', 'Helen', 'Sona', 'Ella'], 'score': [82, 98, 91, 87], 'option_course': ['C#','Python','Java','C']}df = pd.DataFrame(data)#查看分组print(df.groupby('score').groups)输出结果:1{82: Int64Index([0], dtype='int64'),287: Int64Index([3], dtype='int64'),391: Int64Index([2], dtype='int64'),498: Int64Index([1], dtype='int64')}多个列标签分组

当然也可以指定多个列标签进行分组,示例如下:

import pandas as pd

import numpy as np

data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],

'score': [82, 98, 91, 87],

'option_course': ['C#','Python','Java','C']}

df = pd.DataFrame(data)

#查看分组

print(df.groupby(['Name','score']).groups)

输出结果:

1{('Ella', 87): Int64Index([3], dtype='int64'),

2('Helen', 98): Int64Index([1], dtype='int64'),

3('John', 82): Int64Index([0], dtype='int64'),

4('Sona', 91): Int64Index([2], dtype='int64')}

通过 get_group() 方法可以选择组内的具体数据项:

import pandas as pd

import numpy as np

data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],

'score': [82, 98, 91, 87],

'option_course': ['C#','Python','Java','C']}

df = pd.DataFrame(data)

#根据score来分组

grouped=df.groupby('score')

#根据对应组的数据值,选择一个组

print(grouped.get_group(91))

输出结果:

1 Name score option_course

22 Sona 91 Java

遍历分组数据

通过以下方法来遍历分组数据,示例如下:

import pandas as pd

import numpy as np

data = {'Name': ['John', 'Helen', 'Sona', 'Ella'],

'score': [82, 98, 91, 87],

'option_course': ['C#','Python','Java','C']}

df = pd.DataFrame(data)

#查看分组

grouped=df.groupby('score')

for label, option_course in grouped:

#其中key代表分组后字典的键,也就是score

print(label)

#字典对应的值选修的科目

print(option_course)

输出结果:

182

2 Name score option_course

30 John 82 C#

487

5 Name score option_course

63 Ella 87 C

791

8 Name score option_course

92 Sona 91 Java

1098

11 Name score option_course

121 Helen 98 Python

如上所示, groupby 对象的组名称与 score 中的的元素值一一对应。

应用聚合函数

当您在创建 groupby 对象时,通过 agg() 函数可以对分组对象应用多个聚合函数:

import pandas as pd

import numpy as np

data = {'name': ['John', 'Helen', 'Sona', 'Ella'],

'score': [82, 98, 91, 87],

'option_course': ['C#','Python','Java','C']}

df = pd.DataFrame(data)

grouped=df.groupby('name')

#应用一个聚合函数求均值

print(grouped['score']).agg(np.mean)

输出结果:

1name

2Ella 87

3Helen 98

4John 82

5Sona 91

6Name: score, dtype: int64

当然,您也可以一次性应有多个聚合函数,示例如下:

import pandas as pd

import numpy as np

data = {'name': ['John', 'Helen', 'Sona', 'Ella'],

'score': [82, 98, 91, 87],

'option_course': ['C#','Python','Java','C']}

df = pd.DataFrame(data)

grouped=df.groupby('name')

print(grouped['score'].agg([np.size,np.mean,np.std]))

输出结果:

1 size mean std

2name

3Ella 1 87 NaN

4Helen 1 98 NaN

5John 1 82 NaN

6Sona 1 91 NaN

组的转换操作

在组的行或列上可以执行转换操作,最终会返回一个与组大小相同的索引对象。示例如下:

import pandas as pd

import numpy as np

df = pd.DataFrame({'种类':['水果','水果','水果','蔬菜','蔬菜','肉类','肉类'],

'产地':['朝鲜','中国','缅甸','中国','菲律宾','韩国','中国'],

'水果':['橘子','苹果','哈密瓜','番茄','椰子','鱼肉','牛肉'],

'数量':[3,5,5,3,2,15,9],

'价格':[2,5,12,3,4,18,20]})

#分组求均值,水果、蔬菜、肉类

#对可执行计算的数值列求均值

print(df.groupby('种类').transform(np.mean))

#transform()直接应用demean,实现去均值操作

demean = lambda arr:arr-arr.mean()

print(df.groupby('种类').transform(demean))

#自定义函数

# 返回分组的前n行数据

def get_rows(df,n):

#从1到n行的所有列

return df.iloc[:n,:]

#分组后的组名作为行索引

print(df.groupby('种类').apply(get_rows,n=1))

输出结果:

1 数量 价格

20 4.333333 6.333333

31 4.333333 6.333333

42 4.333333 6.333333

53 2.500000 3.500000

64 2.500000 3.500000

75 12.000000 19.000000

86 12.000000 19.000000

9

10 数量 价格

110 -1.333333 -4.333333

121 0.666667 -1.333333

132 0.666667 5.666667

143 0.500000 -0.500000

154 -0.500000 0.500000

165 3.000000 -1.000000

176 -3.000000 1.000000

18

19 种类 产地 水果 数量 价格

20种类

21水果 0 水果 朝鲜 橘子 3 2

22肉类 5 肉类 韩国 鱼肉 15 18

23蔬菜 3 蔬菜 中国 番茄 3 3

组的数据过滤操作

通过 filter() 函数可以实现数据的筛选,该函数根据定义的条件过滤数据并返回一个新的数据集。

下面,筛选出参加比赛超过两次的球队(包含两次):

import pandas as pd

import numpy as np

data = {'Team': ['Riders', 'Riders', 'Devils', 'Devils', 'Kings',

'kings', 'Kings', 'Kings', 'Riders', 'Royals', 'Royals', 'Riders'],

'Rank': [1, 2, 2, 3, 3,4 ,1 ,1,2 , 4,1,2],

'Year': [2014,2015,2014,2015,2014,2015,2016,2017,2016,2014,2015,2017],

'Points':[874,789,863,663,741,802,756,788,694,701,812,698]}

df = pd.DataFrame(data)

#定义lambda函数来筛选数据

print (df.groupby('Team').filter(lambda x: len(x) >= 2))

输出结果:

1 Team Rank Year Points

20 Riders 1 2014 874

31 Riders 2 2015 789

44 Kings 3 2014 741

56 Kings 1 2016 756

67 Kings 1 2017 788

78 Riders 2 2016 694

811 Riders 2 2017 698

二十、pandas merge 合并操作

Pandas 提供的 merge() 函数能够进行高效的合并操作,这与 SQL 关系型数据库的 MERGE 用法非常相似。从字面意思上不难理解,merge 翻译为“合并”,指的是将两个 DataFrame 数据表按照指定的规则进行连接,最后拼接成一个新的 DataFrame 数据表。

merge() 函数的法格式如下:

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,left_index=False, right_index=False, sort=True,suffixes=('_x', '_y'), copy=True)

参数说明,如下表所示:

参数名称说明left/right两个不同的 DataFrame 对象。on指定用于连接的键(即列标签的名字),该键必须同时存在于左右两个 DataFrame 中,如果没有指定,并且其他参数也未指定, 那么将会以两个 DataFrame 的列名交集做为连接键。left_on指定左侧 DataFrame 中作连接键的列名。该参数在左、右列标签名不相同,但表达的含义相同时非常有用。right_on指定左侧 DataFrame 中作连接键的列名。left_index布尔参数,默认为 False。如果为 True 则使用左侧 DataFrame 的行索引作为连接键,若 DataFrame 具有多层 索引(MultiIndex),则层的数量必须与连接键的数量相等。right_index布尔参数,默认为 False。如果为 True 则使用左侧 DataFrame 的行索引作为连接键。how要执行的合并类型,从 {'left', 'right', 'outer', 'inner'} 中取值,默认为“inner”内连接。sort布尔值参数,默认为True,它会将合并后的数据进行排序;若设置为 False,则按照 how 给定的参数值进行排序。suffixes字符串组成的元组。当左右 DataFrame 存在相同列名时,通过该参数可以在相同的列名后附加后缀名,默认为('_x','_y')。copy默认为 True,表示对数据进行复制。

注意:Pandas 库的 merge() 支持各种内外连接,与其相似的还有 join() 函数(默认为左连接)。

下面创建两个不同的 DataFrame,然后对它们进行合并操作:

import pandas as pd

left = pd.DataFrame({

'id':[1,2,3,4],

'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'],

'subject_id':['sub1','sub2','sub4','sub6']})

right = pd.DataFrame({

'id':[1,2,3,4],

'Name': ['William', 'Albert', 'Tony', 'Allen'],

'subject_id':['sub2','sub4','sub3','sub6']})

print (left)

print (right)

输出如下:

1 id Name subject_id

20 1 Smith sub1

31 2 Maiki sub2

42 3 Hunter sub4

53 4 Hilen sub6

6

7 id Name subject_id

80 1 William sub2

91 2 Albert sub4

102 3 Tony sub3

113 4 Allen sub6

在单个键上进行合并操作通过 on 参数指定一个连接键,然后对上述 DataFrame 进行合并操作:import pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4], 'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'], 'subject_id':['sub1','sub2','sub4','sub6']}) right = pd.DataFrame({ 'id':[1,2,3,4], 'Name': ['William', 'Albert', 'Tony', 'Allen'], 'subject_id':['sub2','sub4','sub3','sub6']})#通过on参数指定合并的键print(pd.merge(left,right,on='id'))输出结果:1 id Name_x subject_id_x Name_y subject_id_y20 1 Smith sub1 William sub231 2 Maiki sub2 Albert sub442 3 Hunter sub4 Tony sub353 4 Hilen sub6 Allen sub6在多个键上进行合并操作

下面示例,指定多个键来合并上述两个 DataFrame 对象:

import pandas as pd

left = pd.DataFrame({

'id':[1,2,3,4],

'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'],

'subject_id':['sub1','sub2','sub4','sub6']})

right = pd.DataFrame({

'id':[1,2,3,4],

'Name': ['Bill', 'Lucy', 'Jack', 'Mike'],

'subject_id':['sub2','sub4','sub3','sub6']})

print(pd.merge(left,right,on=['id','subject_id']))

输出结果:

1 id Name_x subject_id Name_y

20 4 Hilen sub6 Mike

使用how参数合并

通过how参数可以确定 DataFrame 中要包含哪些键,如果在左表、右表都不存的键,那么合并后该键对应的值为 NaN。为了便于大家学习,我们将 how 参数和与其等价的 SQL 语句做了总结:

Merge方法等效 SQL描述leftLEFT OUTER JOIN使用左侧对象的keyrightRIGHT OUTER JOIN使用右侧对象的keyouterFULL OUTER JOIN使用左右两侧所有key的并集innerINNER JOIN使用左右两侧key的交集left joinimport pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4], 'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'], 'subject_id':['sub1','sub2','sub4','sub6']}) right = pd.DataFrame({ 'id':[1,2,3,4], 'Name': ['Bill', 'Lucy', 'Jack', 'Mike'], 'subject_id':['sub2','sub4','sub3','sub6']}) #以left侧的subject_id为键print(pd.merge(left,right,on='subject_id',how="left"))输出结果:1 id_x Name_x subject_id id_y Name_y20 1 Smith sub1 NaN NaN31 2 Maiki sub2 1.0 Bill42 3 Hunter sub4 2.0 Lucy53 4 Hilen sub6 4.0 Mikeright joinimport pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4], 'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'], 'subject_id':['sub1','sub2','sub4','sub6']}) right = pd.DataFrame({ 'id':[1,2,3,4], 'Name': ['Bill', 'Lucy', 'Jack', 'Mike'], 'subject_id':['sub2','sub4','sub3','sub6']}) #以right侧的subject_id为键print(pd.merge(left,right,on='subject_id',how="right"))输出结果:1 id_x Name_x subject_id id_y Name_y20 2.0 Maiki sub2 1 Bill31 3.0 Hunter sub4 2 Lucy42 4.0 Hilen sub6 4 Mike53 NaN NaN sub3 3 Jackouter join(并集)import pandas as pd left = pd.DataFrame({ 'id':[1,2,3,4], 'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'], 'subject_id':['sub1','sub2','sub4','sub6']}) right = pd.DataFrame({ 'id':[1,2,3,4], 'Name': ['Bill', 'Lucy', 'Jack', 'Mike'], 'subject_id':['sub2','sub4','sub3','sub6']}) #求出两个subject_id的并集,并作为键print(pd.merge(left,right,on='subject_id',how="outer"))输出结果:1 id_x Name_x subject_id id_y Name_y20 1.0 Smith sub1 NaN NaN31 2.0 Maiki sub2 1.0 Bill42 3.0 Hunter sub4 2.0 Lucy53 4.0 Hilen sub6 4.0 Mike64 NaN NaN sub3 3.0 Jackinner join(交集)

import pandas as pd

left = pd.DataFrame({

'id':[1,2,3,4],

'Name': ['Smith', 'Maiki', 'Hunter', 'Hilen'],

'subject_id':['sub1','sub2','sub4','sub6']})

right = pd.DataFrame({

'id':[1,2,3,4],

'Name': ['Bill', 'Lucy', 'Jack', 'Mike'],

'subject_id':['sub2','sub4','sub3','sub6']})

#求出两个subject_id的交集,并将结果作为键

print(pd.merge(left,right,on='subject_id',how="inner"))

输出结果:

1 id_x Name_x subject_id id_y Name_y

20 2 Maiki sub2 1 Bill

31 3 Hunter sub4 2 Lucy

42 4 Hilen sub6 4 Mike

注意:当 a 与 b 进行内连操作时 a.join(b) 不等于 b.join(a)。

二十一、pandas concat链接操作

Pandas 通过 concat() 函数能够轻松地将 Series 与 DataFrame 对象组合在一起,函数的语法格式如下:

1pd.concat(objs,axis=0,join='outer',join_axes=None,ignore_index=False)

参数说明如下所示:

参数名称说明objs一个序列或者是Series、DataFrame对象。axis表示在哪个轴方向上(行或者列)进行连接操作,默认 axis=0 表示行方向。join指定连接方式,取值为{"inner","outer"},默认为 outer 表示取并集,inner代表取交集。ignore_index布尔值参数,默认为 False,如果为 True,表示不在连接的轴上使用索引。join_axes表示索引对象的列表。concat()

concat() 函数用于沿某个特定的轴执行连接操作。下面让我们创建不同的对象,并对其进行连接。

import pandas as pd

a= pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],

'B': ['B0', 'B1', 'B2', 'B3'],

'C': ['C0', 'C1', 'C2', 'C3'],

'D': ['D0', 'D1', 'D2', 'D3']},

index=[0, 1, 2, 3])

b= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],

'B': ['B4', 'B5', 'B6', 'B7'],

'C': ['C4', 'C5', 'C6', 'C7'],

'D': ['D4', 'D5', 'D6', 'D7']},

#连接a与b

print(pd.concat([a,b]))

输出结果:

1 A B C D

20 A0 B0 C0 D0

31 A1 B1 C1 D1

42 A2 B2 C2 D2

53 A3 B3 C3 D3

64 A4 B4 C4 D4

75 A5 B5 C5 D5

86 A6 B6 C6 D6

97 A7 B7 C7 D7

如果想把指定的键与 DataFrame 对象连接,您可以使用 keys 参数来实现。如下所示:

import pandas as pd

a= pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],

'B': ['B0', 'B1', 'B2', 'B3'],

'C': ['C0', 'C1', 'C2', 'C3'],

'D': ['D0', 'D1', 'D2', 'D3']},

index=[0, 1, 2, 3])

b= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],

'B': ['B4', 'B5', 'B6', 'B7'],

'C': ['C4', 'C5', 'C6', 'C7'],

'D': ['D1', 'D2', 'D5', 'D6']},

index=[2,3,4,5])

#连接a与b,并给a,b连接一个指定的键

print(pd.concat([a,b],keys=['x','y']))

输出结果:

1 A B C D

2x 0 A0 B0 C0 D0

3 1 A1 B1 C1 D1

4 2 A2 B2 C2 D2

5 3 A3 B3 C3 D3

6y 2 A4 B4 C4 D1

7 3 A5 B5 C5 D2

8 4 A6 B6 C6 D5

9 5 A7 B7 C7 D6

上述示中,可以看出行索引 index 存在重复使用的现象,如果想让输出的行索引遵循依次递增的规则,那么需要将 ignore_index 设置为 True。

import pandas as pd

a= pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],

'B': ['B0', 'B1', 'B2', 'B3'],

'C': ['C0', 'C1', 'C2', 'C3'],

'D': ['D0', 'D1', 'D2', 'D3']},

index=[0, 1, 2, 3])

b= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],

'B': ['B4', 'B5', 'B6', 'B7'],

'C': ['C4', 'C5', 'C6', 'C7'],

'D': ['D1', 'D2', 'D5', 'D6']},

index=[2,3,4,5])

#连接a与b,设置 ignore_index 等于 True

print(pd.concat([a,b],keys=['x','y'],ignore_index=True))

输出结果:

1 A B C D

20 A0 B0 C0 D0

31 A1 B1 C1 D1

42 A2 B2 C2 D2

53 A3 B3 C3 D3

64 A4 B4 C4 D1

75 A5 B5 C5 D2

86 A6 B6 C6 D5

97 A7 B7 C7 D6

注意:此时的索引顺序被改变了,而且键 keys 指定的键也被覆盖了。

如果您想要沿着 axis=1 添加两个对象,那么将会追加新的列。

import pandas as pd

a= pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],

'B': ['B0', 'B1', 'B2', 'B3'],

'C': ['C0', 'C1', 'C2', 'C3'],

'D': ['D0', 'D1', 'D2', 'D3']},

index=[0, 1, 2, 3])

b= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],

'B': ['B4', 'B5', 'B6', 'B7'],

'C': ['C4', 'C5', 'C6', 'C7'],

'D': ['D1', 'D2', 'D5', 'D6']},

index=[4,5,6,7])

#沿着 axis=1,连接a与b

print(pd.concat([a,b],axis=1))

输出结果:

1 A B C D A B C D

20 A0 B0 C0 D0 NaN NaN NaN NaN

31 A1 B1 C1 D1 NaN NaN NaN NaN

42 A2 B2 C2 D2 NaN NaN NaN NaN

53 A3 B3 C3 D3 NaN NaN NaN NaN

64 NaN NaN NaN NaN A4 B4 C4 D1

75 NaN NaN NaN NaN A5 B5 C5 D2

86 NaN NaN NaN NaN A6 B6 C6 D5

97 NaN NaN NaN NaN A7 B7 C7 D6

append()

如果要连接 Series 和 DataFrame 对象,有一个最方便、快捷的方法,那就是 append() 方法。该方法沿着 axis=0 (行方向)进行操作。

import pandas as pd

a= pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],

'B': ['B0', 'B1', 'B2', 'B3'],

'C': ['C0', 'C1', 'C2', 'C3'],

'D': ['D0', 'D1', 'D2', 'D3']},

index=[0, 1, 2, 3])

b= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],

'B': ['B4', 'B5', 'B6', 'B7'],

'C': ['C4', 'C5', 'C6', 'C7'],

'D': ['D1', 'D2', 'D5', 'D6']},

index=[4,5,6,7])

#沿着 axis=0,使用 apppend()方法连接a与b

print(a.append(b))

输出结果:

1 A B C D

20 A0 B0 C0 D0

31 A1 B1 C1 D1

42 A2 B2 C2 D2

53 A3 B3 C3 D3

64 A4 B4 C4 D1

75 A5 B5 C5 D2

86 A6 B6 C6 D5

97 A7 B7 C7 D6

当然 append() 函数也可接收多个对象,示例如下:

a= pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],

'B': ['B0', 'B1', 'B2', 'B3'],

'C': ['C0', 'C1', 'C2', 'C3'],

'D': ['D0', 'D1', 'D2', 'D3']},

index=[0, 1, 2, 3])

b= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],

'B': ['B4', 'B5', 'B6', 'B7'],

'C': ['C4', 'C5', 'C6', 'C7'],

'D': ['D1', 'D2', 'D5', 'D6']},

index=[4,5,6,7])

c= pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],

'B': ['B8', 'B9', 'B10', 'B7'],

'C': ['C9', 'C8', 'C7', 'C6'],

'D': ['D8', 'D5', 'D7', 'D6']},

index=[8,9,10,11])

print(a.append(b,c,a))

输出结果:

1 A B C D

20 A0 B0 C0 D0

31 A1 B1 C1 D1

42 A2 B2 C2 D2

53 A3 B3 C3 D3

64 A4 B4 C4 D1

75 A5 B5 C5 D2

86 A6 B6 C6 D5

97 A7 B7 C7 D6

108 A4 B8 C9 D8

119 A5 B9 C8 D5

1210 A6 B10 C7 D7

1311 A7 B7 C6 D6

140 A0 B0 C0 D0

151 A1 B1 C1 D1

162 A2 B2 C2 D2

173 A3 B3 C3 D3

二十二、pandas时间序列

顾名思义,时间序列(time series),就是由时间构成的序列,它指的是在一定时间内按照时间顺序测量的某个变量的取值序列,比如一天内的温度会随时间而发生变化,或者股票的价格会随着时间不断的波动,这里用到的一系列时间,就可以看做时间序列。时间序列包含三种应用场景,分别是:

特定的时刻(timestamp),也就是时间戳;固定的日期(period),比如某年某月某日;时间间隔(interval),每隔一段时间具有规律性;

在处理时间序列的过程中,我们一般会遇到两个问题,第一,如何创建时间序列;第二,如何更改已生成时间序列的频率。 Pandas 为解决上述问题提供了一套简单、易用的方法。

下面用 Python 内置的 datetime 模块来获取当前时间,通过该模块提供的now()方法即可实现。

from datetime import datetime

#数据类型为datetime

print(datetime.now())

输出结果:

12020-12-16 16:36:18.791297

创建时间戳

TimeStamp(时间戳) 是时间序列中的最基本的数据类型,它将数值与时间点完美结合在一起。Pandas 使用下列方法创建时间戳:

import pandas as pd

print (pd.Timestamp('2017-03-01'))

输出结果:

2017-03-01 00:00:00

同样,可以将整型或浮点型表示的时间转换为时间戳。默认的单位是纳秒(时间戳单位),示例如下:

import pandas as pd

print(pd.Timestamp(1587687255,unit='s'))

输出结果:

12022-03-19 14:26:39

创建时间范围

通过 date_range() 方法可以创建某段连续的时间或者固定间隔的时间时间段。该函数提供了三个参数,分别是:

start:开始时间end:结束时间freq:时间频率,默认为 "D"(天)

示例如下:

import pandas as pd

#freq表示时间频率,每30min变化一次

print(pd.date_range("9:00", "18:10", freq="30min").time)

输出结果:

1[datetime.time(9, 0) datetime.time(9, 30) datetime.time(10, 0)

2datetime.time(10, 30) datetime.time(11, 0) datetime.time(11, 30)

3datetime.time(12, 0) datetime.time(12, 30) datetime.time(13, 0)

4datetime.time(13, 30) datetime.time(14, 0) datetime.time(14, 30)

5datetime.time(15, 0) datetime.time(15, 30) datetime.time(16, 0)

6datetime.time(16, 30) datetime.time(17, 0) datetime.time(17, 30)

7datetime.time(18, 0)]

更改时间频率

import pandas as pd

#修改为按小时

print(pd.date_range("6:10", "11:45", freq="H").time)

输出结果:

1[datetime.time(6, 10) datetime.time(7, 10) datetime.time(8, 10)

2datetime.time(9, 10) datetime.time(10, 10) datetime.time(11, 10)]

转化为时间戳

您可以使用 to_datetime() 函数将 series 或 list 转换为日期对象,其中 list 会转换为DatetimeIndex。示例如下:

import pandas as pd

print(pd.to_datetime(pd.Series(['Jun 3, 2020','2020-12-10', None])))

输出结果:

10

22020-06-031

32020-12-10

42 NaT

5dtype: datetime64[ns]

注意:NaT 表示的不是时间 ,它等效于 NaN。

最后再来看一个示例:

import pandas as pd

#传入list,生成Datetimeindex

print(pd.to_datetime(['Jun 31, 2020','2020-12-10', None]))

输出结果:

1DatetimeIndex(['2020-06-03', '2020-12-10', 'NaT'], dtype='datetime64[ns]', freq=None)

频率和周期转换

Time Periods 表示时间跨度,一段时间周期,它被定义在 Pandas Periods 类中,通过该类提供的方法可以实现将频率转换为周期。比如 Periods() 方法,可以将频率 "M"(月)转换为 Period(时间段)。

下面示例,使用 asfreq() 和 start 参数,打印 "01" ,若使用 end 参数,则打印 "31"。示例如下:

import pandas as pd

x = pd.Period('2014', freq='M')

#start参数

x.asfreq('D', 'start')

#end参数

x.asfreq('D', 'end')

输出结果:

1Period('2014-01-01', 'D')

2Period('2014-01-31', 'D')

对于常用的时间序列频率,Pandas 为其规定了一些字符串别名,我们将这些别名称为“offset(偏移量)”。如下表所示:

别名描述别名描述B工作日频率BQS工作季度开始频率D日历日频率A年终频率W每周频率BA工作年度结束频率M月末频率BAS工作年度开始频率SM半月结束频率BH营业时间频率BM工作月结束频率H小时频率MS月开始频率T,min每分钟频率SMS半月开始频率S每秒钟频率BMS工作月开始频率L,ms毫秒Q季末频率U,us微妙BQ工作季度结束频率N纳秒QS季度开始频率时间周期计算

周期计算,指的是对时间周期进行算术运算,所有的操作将在“频率”的基础上执行。

import pandas as pd

#S表示秒

x = pd.Period('2014', freq='S')

x

输出结果:

1Period('2014-01-01 00:00:00', 'S')

执行计算示例:

import pandas as pd

x = pd.Period('2014', freq='S')

#加1s的时间

print(x+1)

输出结果:

1Period('2014-01-01 00:00:01', 'S')

再看一组完整的示例:

#定义时期period,默认freq="Y"年份

p1=pd.Period('2020')

p2=pd.Period('2019')

#使用f''格式化输出

print(f'p1={p1}年')

print(f'p2={p2}年')

print(f'p1和p2间隔{p1-p2}年')

#f''表示字符串格式化输出

print(f'五年前是{p1-5}年')

输出结果:

1p1=2020年

2p2=2019年

3p1和p2间隔年

4五年前是2015年

创建时间周期

我们可以使用 period_range() 方法来创建时间周期范围。示例如下:

import pandas as pd

#Y表示年

p = pd.period_range('2016','2018', freq='Y')

p

输出结果:

1PeriodIndex(['2016', '2017', '2018'], dtype='period[A-DEC]', freq='A-DEC')

时间序列转换

如果想要把字符串日期转换为 Period,首先需要将字符串转换为日期格式,然后再将日期转换为 Period。示例如下:

# 创建时间序列

index=pd.date_range("2020-03-17","2020-03-30",freq="1.5H")

#随机选取4个互不相同的数

loc=np.random.choice(np.arange(len(index)),size=4,replace=False)

loc.sort()

ts_index=index[loc]

ts_index

pd_index=ts_index.to_periods('D')

pd_index()

输出结果:

1DatetimeIndex(['2020-03-17 12:00:00', '2020-03-22 04:30:00',

2 '2020-03-27 03:00:00', '2020-03-30 00:00:00'],

3 dtype='datetime64[ns]', freq=None)

4

5PeriodIndex(['2020-03-17', '2020-03-19', '2020-03-19', '2020-03-27'], dtype='period[D]', freq='D')

使用 to_timestamp() 能够将 Period 时期转换为时间戳(timestamp),示例如下:

import pandas as pd

p1=pd.Periods("2020-2-3")

p1.to_timestamp()

输出结果:

1Timestamp('2020-02-03 00:00:00')

创建日期范围

Pandas 提供了用来创建日期序列的函数 date_range(),该函数的默认频率为 "D", 也就是“天”。日期序列只包含年、月、日,不包含时、分、秒。

下面是一组简单的示例,如下所示:

import pandas as pd

print(pd.date_range('12/15/2020', periods=10))

输出结果:

DatetimeIndex(['2020-12-15', '2020-12-16', '2020-12-17', '2020-12-18', '2020-12-19', '2020-12-20', '2020-12-21', '2020-12-22', '2020-12-23', '2020-12-24'], dtype='datetime64[ns]', freq='D')

当我们使用 date_range() 来创建日期范围时,该函数包含结束的日期,用数学术语来说就是区间左闭右闭,即包含起始值,也包含结束值。示例如下:

import pandas as pd

#建议使用Python的datetime模块创建时间

start = pd.datetime(2019, 1, 1)

end = pd.datetime(2019, 1, 5)

print pd.date_range(start,end)

输出结果:

1DatetimeIndex(['2019-01-01', '2019-01-02', '2019-01-03', '2019-01-04','2019-01-05']

2,dtype='datetime64[ns]', freq='D')

更改日频率

使用下列方法可以修改频率,比如按“天”为按“月”,示例如下:

import pandas as pd

print(pd.date_range('12/15/2011', periods=5,freq='M'))

输出结果:

1DatetimeIndex(['2020-12-31', '2021-01-31', '2021-02-28', '2021-03-31',

2 '2021-04-30'],dtype='datetime64[ns]', freq='M')

工作日时间

bdate_range() 表示创建工作日的日期范围,它与 date_range() 不同,它不包括周六、周日。

import pandas as pd

print(pd.date_range('11/25/2020', periods=8))

输出结果:

1DatetimeIndex(['2020-11-25', '2020-11-26', '2020-11-27', '2020-11-28','2020-11-29', '2020-11-30', '2020-12-01', '2020-12-02'],dtype='datetime64[ns]', freq='D')

上述方法中,date_range() 默认频率是日历日,而 bdate_range() 的默认频率是工作日。

二十三、pandas 日期时间格式化

当进行数据分析时,我们会遇到很多带有日期、时间格式的数据集,在处理这些数据集时,可能会遇到日期格式不统一的问题,此时就需要对日期时间做统一的格式化处理。比如“Wednesday, June 6, 2020”可以写成“6/6/20”,或者写成“06-06-2020。

日期格式化符号

在对时间进行格式化处理时,它们都有固定的表示格式,比如小时的格式化符号为%H ,分钟简写为%M ,秒简写为%S。下表对常用的日期格式化符号做了总结:

日期格式化符号符号说明%y两位数的年份表示(00-99)%Y四位数的年份表示(000-9999)%m月份(01-12)%d月内中的一天(0-31)%H24小时制小时数(0-23)%I12小时制小时数(01-12)%M分钟数(00=59)%S秒(00-59)%a本地英文缩写星期名称%A本地英文完整星期名称%b本地缩写英文的月份名称%B本地完整英文的月份名称%w星期(0-6),星期天为星期的开始%W一年中的星期数(00-53)星期一为星期的开始%x本地相应的日期表示%X本地相应的时间表示%Z当前时区的名称%U一年中的星期数(00-53)星期天为星期的开始%j年内的一天(001-366)%c本地相应的日期表示和时间表示Python处理

Python 内置的 strptime() 方法能够将字符串日期转换为 datetime 类型,下面看一组示例:

from datetime import datetime

#将日期定义为字符串

date_str1 = 'Wednesday, July 18, 2020'

date_str2 = '18/7/20'

date_str3 = '18-07-2020'

#将日期转化为datetime对象

dmy_dt1 = datetime.strptime(date_str1, '%A,%B%d,%Y')

dmy_dt2 = datetime.strptime(date_str2, '%d/%m/%y')

dmy_dt3 = datetime.strptime(date_str3, '%d-%m-%Y')

#处理为相同格式,并打印输出

print(dmy_dt1)

print(dmy_dt2)

print(dmy_dt3)

输出结果:

12020-07-18 00:00:00

22020-07-18 00:00:00

32020-07-18 00:00:00

注意:strftime() 可以将 datetime 类型转换为字符串类型,恰好与 strptime() 相反。

Pandas处理

除了使用 Python 内置的 strptime() 方法外,你还可以使用 Pandas 模块的 pd.to_datetime() 和 pd.DatetimeIndex() 进行转换。

to_datetime()通过 to_datetime() 直接转换为 datetime 类型import pandas as pdimport numpy as npdate = ['2012-05-06 11:00:00','2012-05-16 11:00:00']pd_date=pd.to_datetime(date)df=pd.Series(np.random.randn(2),index=pd_date)DatetimeIndex()

使用 Datetimeindex() 函数设置时间序,示例如下:

date = pd.DatetimeIndex(['1/1/2008', '1/2/2008', '1/3/2008', '1/4/2008', '1/5/2008'])

dt = pd.Series(np.random.randn(5),index = date)

print(dt)

输出结果:

12008-01-01 1.965619

22008-01-02 -2.897374

32008-01-03 0.625929

42008-01-04 1.204926

52008-01-05 1.755680

6dtype: float64

二十四、pandas Timedelta时间差

Timedelta 表示时间差(或者时间增量),我们可以使用不同的时间单位来表示它,比如,天、小时、分、秒。时间差的最终的结果可以是正时间差,也可以是负时间差。

本节主要介绍创建 Timedelta (时间差)的方法以及与时间差相关的运算法则。

字符串

通过传递字符串可以创建 Timedelta 对象,示例如下:

import pandas as pd

print(pd.Timedelta('5 days 8 hours 6 minutes 59 seconds'))

输出结果:

15 days 08:06:59

整数

通过传递整数值和unit参数也可以创建一个 Timedelta 对象。

import pandas as pd

print(pd.Timedelta(19,unit='h'))

输出结果:

10 days 19:00:00

数据偏移量

数据偏移量, 比如,周(weeks)、天(days)、小时(hours)、分钟(minutes)、秒(milliseconds)、毫秒、微秒、纳秒都可以使用。

import pandas as pd

print (pd.Timedelta(days=2,hours=6))

输出结果:

12 days 06:00:00

to_timedelta()

您可以使用pd.to_timedelta()方法,将具有 timedelta 格式的值 (标量、数组、列表或 Series)转换为 Timedelta 类型。如果输入是 Series,则返回 Series;如果输入是标量,则返回值也为标量,其他情况输出 TimedeltaIndex。示例如下:

import pandas as pd

print(pd.to_timedelta(['1 days 06:05:01.00003', '15.5us', 'nan']))

print(pd.to_timedelta(np.arange(5), unit='s'))

输出结果:

1TimedeltaIndex(['1 days 06:05:01.000030', '0 days 00:00:00.000015', NaT],dtype='timedelta64[ns]', freq=None)

2

3TimedeltaIndex(['0 days 00:00:00', '0 days 00:00:01', '0 days 00:00:02','0 days 00:00:03',

4'0 days 00:00:04'],dtype='timedelta64[ns]', freq=None)

算术操作

通过对datetime64[ns]类型的时间序列或时间戳做算术运算,其运算结果依然是datetime64[ns]数据类型。接下来,我们创建一个带有 Timedelta 与 datetime 的 DataFrame 对象,并对其做一些算术运算。

import pandas as pd

s = pd.Series(pd.date_range('2020-1-1', periods=5, freq='D'))

#推导式用法

td = pd.Series([ pd.Timedelta(days=i) for i in range(5)])

df = pd.DataFrame(dict(A = s, B = td))

print(df)

输出结果:

1 A B

20 2020-01-01 0 days

31 2020-01-02 1 days

42 2020-01-03 2 days

53 2020-01-04 3 days

64 2020-01-05 4 days

加法运算

import pandas as pd

s = pd.Series(pd.date_range('20120-1-1', periods=3, freq='D'))

td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ])

df = pd.DataFrame(dict(A = s, B = td))

#加法运算

df['C']=df['A']+df['B']

print(df)

输出结果:

1 A B C

20 2020-01-01 0 days 2020-01-01

31 2020-01-02 1 days 2020-01-03

42 2020-01-03 2 days 2020-01-05

减法运算

import pandas as pd

s = pd.Series(pd.date_range('2012-1-1', periods=3, freq='D'))

td = pd.Series([ pd.Timedelta(days=i) for i in range(3) ])

df = pd.DataFrame(dict(A = s, B = td))

df['C']=df['A']+df['B']

df['D']=df['C']-df['B']

print(df)

输出结果:

1 A B C D

20 2019-01-01 0 days 2019-01-01 2019-01-01

31 2019-01-02 1 days 2019-01-03 2019-01-02

42 2019-01-03 2 days 2019-01-05 2019-01-03

二十五、pandas sample 随机抽样

随机抽样,是统计学中常用的一种方法,它可以帮助我们从大量的数据中快速地构建出一组数据分析模型。在 Pandas 中,如果想要对数据集进行随机抽样,需要使用 sample() 函数。

sample() 函数的语法格式如下:

1DataFrame.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)

参数说明如下表所示:

参数名称参数说明n表示要抽取的行数。frac表示抽取的比例,比如 frac=0.5,代表抽取总体数据的50%。replace布尔值参数,表示是否以有放回抽样的方式进行选择,默认为 False,取出数据后不再放回。weights可选参数,代表每个样本的权重值,参数值是字符串或者数组。random_state可选参数,控制随机状态,默认为 None,表示随机数据不会重复;若为 1 表示会取得重复数据。axis表示在哪个方向上抽取数据(axis=1 表示列/axis=0 表示行)。

该函数返回与数据集类型相同的新对象,相当于 numpy.random.choice()。实例如下:

import pandas as pd

dict = {'name':["Jack", "Tom", "Helen", "John"],'age': [28, 39, 34, 36],'score':[98,92,91,89]}

info = pd.DataFrame(dict)

#默认随机选择两行

info.sample(n=2)

#随机选择两列

info.sample(n=2,axis=1)

输出结果:

1 name age score

23 John 36 89

30 Jack 28 98

4

5 score name

60 98 Jack

71 92 Tom

82 91 Helen

93 89 John

再来看一组示例:

import pandas as pd

info = pd.DataFrame({'data1': [2, 6, 8, 0], 'data2': [2, 5, 0, 8], 'data3': [12, 2, 1, 8]}, index=['John', 'Parker', 'Smith', 'William'])

info

#随机抽取3个数据

info['data1'].sample(n=3)

#总体的50%

info.sample(frac=0.5, replace=True)

#data3序列为权重值,并且允许重复数据出现

info.sample(n=2, weights='data3', random_state=1)

输出结果:

1随机选择3行数据:

2William 0

3Smith 8

4Parker 6

5Name: data1, dtype: int64

6

7 data1 data2 data3

8John 2 2 12

9William 0 8 8

10

11 data1 data2 data3

12John 2 2 12

13William 0 8 8

二十六、pandas resample 数据重采样

数据重采样是将时间序列从一个频率转换至另一个频率的过程,它主要有两种实现方式,分别是降采样和升采样,降采样指将高频率的数据转换为低频率,升采样则与其恰好相反,说明如下:

方法说明降采样将高频率(间隔短)数据转换为低频率(间隔长)。升采样将低频率数据转换为高频率。

Pandas 提供了 resample() 函数来实现数据的重采样。

降采样

通过 resample() 函数完成数据的降采样,比如按天计数的频率转换为按月计数。

import pandas as pd

import numpy as np

rng = pd.date_range('1/1/2021',periods=100,freq='D')

ts = pd.Series(np.random.randn(len(rng)),index=rng)

#降采样后并聚合

ts.resample('M').mean()

输出结果:

12021-01-31 0.210353

22021-02-28 -0.058859

32021-03-31 -0.182952

42021-04-30 0.205254

5Freq: M, dtype: float64

如果您只想看到月份,那么您可以设置kind=period如下所示:

ts.resample('M',kind='period').mean()

输出结果:

12021-01 -0.153121

22021-02 0.136231

32021-03 -0.238975

42021-04 -0.309502

5Freq: M, dtype: float64

升采样

升采样是将低频率(时间间隔)转换为高频率,示例如下:

import pandas as pd

import numpy as np

#生成一份时间序列数据

rng = pd.date_range('1/1/2021', periods=20, freq='3D')

ts = pd.Series(np.random.randn(len(rng)), index=rng)

print(ts.head())

#使用asfreq()在原数据基础上实现频率转换

ts.resample('D').asfreq().head()

输出结果:

1升采样前:

22021-01-01 0.608716

32021-01-04 1.097451

42021-01-07 -1.280173

52021-01-10 -0.175065

62021-01-13 1.046831

7Freq: 3D, dtype: float64

8升采样后:

92021-01-01 0.608716

102021-01-02 NaN

112021-01-03 NaN

122021-01-04 1.097451

132021-01-05 NaN

14Freq: D, dtype: float64

频率转换

asfreq() 方法不仅能够实现频率转换,还可以保留原频率对应的数值,同时它也可以单独使用,示例如下:

index = pd.date_range('1/1/2021', periods=6, freq='T')

series = pd.Series([0.0, None, 2.0, 3.0,4.0,5.0], index=index)

df = pd.DataFrame({'s':series})

print(df.asfreq("45s"))

输出结果:

1 num

22021-01-01 00:00:00 0.0

32021-01-01 00:00:45 NaN

42021-01-01 00:01:30 NaN

52021-01-01 00:02:15 NaN

62021-01-01 00:03:00 3.0

72021-01-01 00:03:45 NaN

82021-01-01 00:04:30 NaN

插值处理

从上述示例不难看出,升采样的结果会产生缺失值,那么就需要对缺失值进行处理,一般有以下几种处理方式:

方法说明pad/ffill用前一个非缺失值去填充缺失值。backfill/bfill用后一个非缺失值去填充缺失值。interpolater('linear')线性插值方法。fillna(value)指定一个值去替换缺失值。

下面使用插值方法处理 NaN 值,示例如下:

import pandas as pd

import numpy as np

#创建时间序列数据

rng = pd.date_range('1/1/2021', periods=20, freq='3D')

ts = pd.Series(np.random.randn(len(rng)), index=rng)

print(ts.resample('D').asfreq().head())

#使用ffill处理缺失值

ts.resample('D').asfreq().ffill().head()

输出结果:

12021-01-01 0.555580

22021-01-02 NaN

32021-01-03 NaN

42021-01-04 -0.079324

52021-01-05 NaN

6Freq: D, dtype: float64

7

8#插值处理,注意对比

92021-01-01 0.555580

102021-01-02 0.555580

112021-01-03 0.555580

122021-01-04 -0.079324

132021-01-05 -0.079324

14Freq: D, dtype: float64

二十七、pandas 分类对象

通常情况下,数据集中会存在许多同一类别的信息,比如相同国家、相同行政编码、相同性别等,当这些相同类别的数据多次出现时,就会给数据处理增添许多麻烦,导致数据集变得臃肿,不能直观、清晰地展示数据。

针对上述问题,Pandas 提供了分类对象(Categorical Object),该对象能够实现有序排列、自动去重的功能,但是它不能执行运算。本节,我们了解一下分类对象的使用。

对象创建

我们可以通过多种方式创建分类对象,下面介绍以下两种方法:

指定dtype创建import pandas as pds = pd.Series(["a","b","c","a"], dtype="category")print(s)输出结果:10 a21 b32 c43 a5dtype: category6Categories (3, object): [a, b, c]通过上述示例,您可能会注意到,虽然传递给 Series 四个元素值,但是它的类别为 3,这是因为 a 的类别存在重复。pd.Categorical

通过 Category 的构造函数,您可以创建一个类别对象。构造函数,如下所示:

pandas.Categorical(values, categories, ordered)

values:以列表的形式传参,表示要分类的值。ordered:布尔值,默认为 False,若为 Ture,表示对分类的数据进行排序。dtype:返回一个 category 类型,表示分类对象。

示例如下:

import pandas as pd

#自动按a、b、c分类

cat = pd.Categorical(['a', 'b', 'c', 'a', 'b', 'c'])

print(cat)

输出结果:

1[a, b, c, a, b, c]

2Categories (3, object): [a, b, c]

再看一组示例:

import pandas as pd

cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a'])

print(cat)

输出结果:

1[a, b, c, a, b, c, NaN]

2Categories (3, object): [c, b, a]

上述示例中,第二个参数值表示类别,当列表中不存在某一类别时,会自动将类别值设置为 NA。

通过指定ordered=True来实现有序分类。示例如下:

import pandas as pd

cat=pd.Categorical(['a','b','c','a','b','c','d'], ['c', 'b', 'a'],ordered=True)

print(cat)

#求最小值

print(cat.min())

输出结果:

1[a, b, c, a, b, c, NaN]

2Categories (3, object): [c < b < a]

3c

获取统计信息

对已经分类的数据使用 describe() 方法,您会得到和数据统计相关的摘要信息。

import pandas as pd

import numpy as np

cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])

df = pd.DataFrame({"cat":cat, "s":["a", "c", "c", np.nan]})

print(df.describe())

print(df["cat"].describe())

输出结果:

1 cat s

2count 3 3

3unique 2 2

4top c c

5freq 2 2

6

7count 3

8unique 2

9top c

10freq 2

11Name: cat, dtype: object

获取类别属性

使用obj.categories命令可以获取对象的类别信息。示例如下:

import pandas as pd

import numpy as np

s = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])

print (s.categories)

输出结果:

Index(['b', 'a', 'c'], dtype='object')

通过 obj.order 可以获取 order 指定的布尔值:

import pandas as pd

import numpy as np

cat = pd.Categorical(["a", "c", "c", np.nan], categories=["b", "a", "c"])

#False表示未指定排序

print (cat.ordered)

输出结果:

1False

重命名类别

要想对类别实现重命名,可以通过 Series.cat.categories 来实现的,示例如下:

import pandas as pd

s = pd.Series(["a","b","c","a"], dtype="category")

#对类名重命名

s.cat.categories = ["Group %s" % g for g in s.cat.categories]

print(s.cat.categories)

输出结果:

1Index(['Group a', 'Group b', 'Group c'], dtype='object')

追加新类别

使用 s.cat.add_categories() 方法,可以追加新类别。

import pandas as pd

s = pd.Series(["a","b","c","a"], dtype="category")

#追加新类别

s = s.cat.add_categories([5])

#查看现有类别

print(s.cat.categories)

输出结果:

1Index(['a', 'b', 'c', 5], dtype='object')

删除类别

使用 remove_categories() 方法,可以删除不需要的类别。示例如下:

import pandas as pd

s = pd.Series(["a","b","c","a"], dtype="category")

#原序列

print(s)

#删除后序列

print(s.cat.remove_categories("a"))

输出结果

10 a

21 b

32 c

43 a

5dtype: category

6Categories (3, object): [a, b, c]

7

80 NaN

91 b

102 c

113 NaN

12dtype: category

13Categories (2, object): [b, c]

分类对象比较

在下述两种情况下,我们可以对分类对象进行比较:

当两个类别对象长度相同时,可以进行比较运算;当两个类别的 ordered 均等于 True,并且类别相同时,可以进行比较运算,比如 ==,!=,>,>=,< 和



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3