1W+字概括精髓,Pandas中必知必会50例

x33g5p2x  于2021-11-13 转载在 其他  
字(11.2k)|赞(0)|评价(0)|浏览(324)

本篇我们继续前面pandas系列教程的探讨,今天我会介绍pandas库当中一些非常实用的方法与函数,希望大家看了之后会有所收获,喜欢本文点赞支持,欢迎收藏学习,文末提供技术交流,欢迎畅聊!

准备需要的数据集

我们先准备生成一些随机数,作为后面需要用到的数据集

  1. index = pd.date_range("1/1/2000", periods=8)
  2. series = pd.Series(np.random.randn(5), index=["a", "b", "c", "d", "e"])
  3. df = pd.DataFrame(np.random.randn(8, 3), index=index, columns=["A", "B", "C"])

Head and tail

head()tail()方法是用来查看数据集当中的前几行和末尾几行的,默认是查看5行,当然读者朋友也可以自行设定行数

  1. series2 = pd.Series(np.random.randn(100))
  2. series2.head()

output

  1. 0 0.733801
  2. 1 -0.740149
  3. 2 -0.031863
  4. 3 2.515542
  5. 4 0.615291
  6. dtype: float64

同理

  1. series2.tail()

output

  1. 95 -0.526625
  2. 96 -0.234975
  3. 97 0.744299
  4. 98 0.434843
  5. 99 -0.609003
  6. dtype: float64

数据的统计分析

pandas当中用describe()方法来对表格中的数据做一个概括性的统计分析,例如

  1. series2.describe()

output

  1. count 100.000000
  2. mean 0.040813
  3. std 1.003012
  4. min -2.385316
  5. 25% -0.627874
  6. 50% -0.029732
  7. 75% 0.733579
  8. max 2.515542
  9. dtype: float64

当然,我们也可以设置好输出的分位

  1. series2.describe(percentiles=[0.05, 0.25, 0.75, 0.95])

output

  1. count 100.000000
  2. mean 0.040813
  3. std 1.003012
  4. min -2.385316
  5. 5% -1.568183
  6. 25% -0.627874
  7. 50% -0.029732
  8. 75% 0.733579
  9. 95% 1.560211
  10. max 2.515542
  11. dtype: float64

对于离散型的数据来说,describe()方法给出的结果则会简洁很多

  1. s = pd.Series(["a", "a", "b", "b", "a", "a", "d", "c", "d", "a"])
  2. s.describe()

output

  1. count 10
  2. unique 4
  3. top a
  4. freq 5
  5. dtype: object

要是表格中既包含了离散型数据,也包含了连续型的数据,默认的话,describe()是会针对连续型数据进行统计分析

  1. df2 = pd.DataFrame({"a": ["Yes", "Yes", "No", "No"], "b": np.random.randn(4)})
  2. df2.describe()

output

  1. b
  2. count 4.000000
  3. mean 0.336053
  4. std 1.398306
  5. min -1.229344
  6. 25% -0.643614
  7. 50% 0.461329
  8. 75% 1.440995
  9. max 1.650898

当然我们也可以指定让其强制统计分析离散型数据或者连续型数据

  1. df2.describe(include=["object"])

output

  1. a
  2. count 4
  3. unique 2
  4. top Yes
  5. freq 2

同理,我们也可以指定连续型的数据进行统计分析

  1. df2.describe(include=["number"])

output

  1. b
  2. count 4.000000
  3. mean -0.593695
  4. std 0.686618
  5. min -1.538640
  6. 25% -0.818440
  7. 50% -0.459147
  8. 75% -0.234401
  9. max 0.082155

如果我们都要去做统计分析,可以这么来执行

  1. df2.describe(include="all")

output

  1. a b
  2. count 4 4.000000
  3. unique 2 NaN
  4. top Yes NaN
  5. freq 2 NaN
  6. mean NaN 0.292523
  7. std NaN 1.523908
  8. min NaN -1.906221
  9. 25% NaN -0.113774
  10. 50% NaN 0.789560
  11. 75% NaN 1.195858
  12. max NaN 1.497193

最大/最小值的位置

idxmin()idxmax()方法是用来查找表格当中最大/最小值的位置,返回的是值的索引

  1. s1 = pd.Series(np.random.randn(5))
  2. s1

output

  1. s1.idxmin(), s1.idxmax()

output

  1. (0, 3)

用在DataFrame上面的话,如下

  1. df1 = pd.DataFrame(np.random.randn(5, 3), columns=["A", "B", "C"])
  2. df1.idxmin(axis=0)

output

  1. A 4
  2. B 2
  3. C 1
  4. dtype: int64

同理,我们将axis参数改成1

  1. df1.idxmin(axis=1)

output

  1. 0 C
  2. 1 C
  3. 2 C
  4. 3 B
  5. 4 A
  6. dtype: object

value_counts()方法

pandas当中的value_counts()方法主要用于数据表的计数以及排序,用来查看表格当中,指定列有多少个不同的数据值并且计算不同值在该列当中出现的次数,先来看一个简单的例子

  1. df = pd.DataFrame({'城市': ['北京', '广州', '上海', '上海', '杭州', '成都', '香港', '南京', '北京', '北京'],
  2. '收入': [10000, 10000, 5500, 5500, 4000, 50000, 8000, 5000, 5200, 5600],
  3. '年龄': [50, 43, 34, 40, 25, 25, 45, 32, 25, 25]})
  4. df["城市"].value_counts()

output

  1. 北京 3
  2. 上海 2
  3. 广州 1
  4. 杭州 1
  5. 成都 1
  6. 香港 1
  7. 南京 1
  8. Name: 城市, dtype: int64

可以看到北京出现了3次,上海出现了2次,并且默认采用的是降序来排列的,下面我们来看一下用升序的方式来排列一下收入这一列

  1. df["收入"].value_counts(ascending=True)

output

  1. 4000 1
  2. 50000 1
  3. 8000 1
  4. 5000 1
  5. 5200 1
  6. 5600 1
  7. 10000 2
  8. 5500 2
  9. Name: 收入, dtype: int64

同时里面也还可以利用参数normalize=True,来计算不同值的计数占比

  1. df['年龄'].value_counts(ascending=True,normalize=True)

output

  1. 50 0.1
  2. 43 0.1
  3. 34 0.1
  4. 40 0.1
  5. 45 0.1
  6. 32 0.1
  7. 25 0.4
  8. Name: 年龄, dtype: float64

数据分组

我们可以使用cut()方法以及qcut()方法来对表格中的连续型数据分组,首先我们看一下cut()方法,假设下面这组数据代表的是小组每个成员的年龄

  1. ages = np.array([2,3,10,40,36,45,58,62,85,89,95,18,20,25,35,32])
  2. pd.cut(ages, 5)

output

  1. [(1.907, 20.6], (1.907, 20.6], (1.907, 20.6], (39.2, 57.8], (20.6, 39.2], ..., (1.907, 20.6], (1.907, 20.6], (20.6, 39.2], (20.6, 39.2], (20.6, 39.2]]
  2. Length: 16
  3. Categories (5, interval[float64, right]): [(1.907, 20.6] < (20.6, 39.2] < (39.2, 57.8] <
  4. (57.8, 76.4] < (76.4, 95.0]]

由上可以看到用cut()方法将数据平分成了5个区间,且区间两边都有扩展以包含最大值和最小值,当然我们也可以给每一个区间加上标记

  1. pd.cut(ages, 5, labels=[u"婴儿",u"少年",u"青年",u"中年",u"老年"])

output

  1. ['婴儿', '婴儿', '婴儿', '青年', '少年', ..., '婴儿', '婴儿', '少年', '少年', '少年']
  2. Length: 16
  3. Categories (5, object): ['婴儿' < '少年' < '青年' < '中年' < '老年']

而对于qcut()方法来说,我们可以指定区间来进行分组,例如

  1. pd.qcut(ages, [0,0.5,1], labels=['小朋友','大孩子'])

output

  1. ['小朋友', '小朋友', '小朋友', '大孩子', '大孩子', ..., '小朋友', '小朋友', '小朋友', '小朋友', '小朋友']
  2. Length: 16
  3. Categories (2, object): ['小朋友' < '大孩子']

这里将年龄这组数据分成两部分[0, 0.5, 1],一组是标上标记小朋友,另一组是大孩子,不过通常情况下,我们用的cut()方法比较多

引用函数

要是在表格当中引用其他的方法,或者是自建的函数,可以使用通过pandas当中的以下这几个方法

  • pipe()
  • apply()applymap()
  • agg()transform()
pipe()方法

首先我们来看pipe()这个方法,我们可以将自己定义好的函数,以链路的形式一个接着一个传给我们要处理的数据集上

  1. def extract_city_name(df):
  2. df["state_name"] = df["state_and_code"].str.split(",").str.get(0)
  3. return df
  4. def add_country_name(df, country_name=None):
  5. df["state_and_country"] = df["state_name"] + country_name
  6. return df

然后我们用pip()这个方法来将上面我们定义的函数串联起来

  1. df_p = pd.DataFrame({"city_and_code": ["Arizona, AZ"]})
  2. df_p = pd.DataFrame({"state_and_code": ["Arizona, AZ"]})
  3. df_p.pipe(extract_city_name).pipe(add_country_name, country_name="_USA")

output

  1. state_and_code state_name state_and_country
  2. 0 Arizona, AZ Arizona Arizona_USA
apply()方法和applymap()方法

apply()方法可以对表格中的数据按照行或者是列方向进行处理,默认是按照列方向,如下

  1. df.apply(np.mean)

output

  1. A -0.101751
  2. B -0.360288
  3. C -0.637433
  4. dtype: float64

当然,我们也可以通过axis参数来进行调节

  1. df.apply(np.mean, axis = 1)

output

  1. 0 -0.803675
  2. 1 -0.179640
  3. 2 -1.200973
  4. 3 0.156888
  5. 4 0.381631
  6. 5 0.049274
  7. 6 1.174923
  8. 7 0.612591
  9. dtype: float64

除此之外,我们也可以直接调用匿名函数lambda的形式

  1. df.apply(lambda x: x.max() - x.min())

output

  1. A 1.922863
  2. B 2.874672
  3. C 1.943930
  4. dtype: float64

也可以调用自己定义的函数方法

  1. df = pd.DataFrame(np.random.randn(5, 3), columns=["A", "B", "C"])
  2. def normalize(x):
  3. return (x - x.mean()) / x.std()

我们用上apply()方法

  1. df.apply(normalize)

output

  1. A B C
  2. 0 1.149795 0.390263 -0.813770
  3. 1 0.805843 -0.532374 0.859627
  4. 2 0.047824 -0.085334 -0.067179
  5. 3 -0.903319 -1.215023 1.149538
  6. 4 -1.100144 1.442467 -1.128216

apply()方法作用于数据集当中的每个行或者是列,而applymap()方法则是对数据集当中的所有元素都进行处理

  1. df = pd.DataFrame({'key1' : ['a', 'c', 'b', 'b', 'd'],
  2. 'key2' : ['one', 'two', 'three', 'two', 'one'],
  3. 'data1' : np.arange(1, 6),
  4. 'data2' : np.arange(10,15)})

output

  1. key1 key2 data1 data2
  2. 0 a one 1 10
  3. 1 c two 2 11
  4. 2 b three 3 12
  5. 3 b four 4 13
  6. 4 d five 5 14

我们来自定义一个函数

  1. def add_A(x):
  2. return "A" + str(x)
  3. df.applymap(add_A)

output

  1. key1 key2 data1 data2
  2. 0 Aa Aone A1 A10
  3. 1 Ac Atwo A2 A11
  4. 2 Ab Athree A3 A12
  5. 3 Ab Afour A4 A13
  6. 4 Ad Afive A5 A14

我们然后也可以通过lambda()自定义函数方法,然后来去除掉这个A

  1. df.applymap(add_A).applymap(lambda x: x.split("A")[1])

output

  1. key1 key2 data1 data2
  2. 0 a one 1 10
  3. 1 c two 2 11
  4. 2 b three 3 12
  5. 3 b four 4 13
  6. 4 d five 5 14

agg()方法和transform()方法

agg()方法本意上是聚合函数,我们可以将用于统计分析的一系列方法都放置其中,并且放置多个

  1. df = pd.DataFrame(np.random.randn(5, 3), columns=["A", "B", "C"])
  2. df.agg(np.sum)

output

  1. A 0.178156
  2. B 3.233845
  3. C -0.859622
  4. dtype: float64

当然,当中的np.sum部分也可以用字符串来表示,例如

  1. df.agg("sum")

output

  1. A -0.606484
  2. B -1.491742
  3. C -1.732083
  4. dtype: float64

我们尝试在当中放置多个统计分析的函数方法

  1. df.agg(["sum", "mean", "median"])

output

  1. A B C
  2. sum 1.964847 3.855801 0.630042
  3. mean 0.392969 0.771160 0.126008
  4. median 0.821005 0.714804 -0.273685

当然我们也可以和lambda匿名函数混合着搭配

  1. df.agg(["sum", lambda x: x.mean()])

output

  1. A B C
  2. sum -0.066486 -1.288341 -1.236244
  3. <lambda> -0.013297 -0.257668 -0.247249

或者和自己定义的函数方法混合着用

  1. def my_mean(x):
  2. return x.mean()
  3. df.agg(["sum", my_mean])

output

  1. A B C
  2. sum -4.850201 -1.544773 0.429007
  3. my_mean -0.970040 -0.308955 0.085801

与此同时,我们在agg()方法中添加字典,实现不同的列使用不同的函数方法

  1. df.agg({"A": "sum", "B": "mean"})

output

  1. A -0.801753
  2. B 0.097550
  3. dtype: float64

例如

  1. df.agg({"A": ["sum", "min"], "B": "mean"})

output

  1. A B
  2. sum 0.911243 NaN
  3. min -0.720225 NaN
  4. mean NaN 0.373411

而当数据集当中既有连续型变量,又有离散型变量的时候,用agg()方法则就会弄巧成拙了

  1. df = pd.DataFrame(
  2. {
  3. "A": [1, 2, 3],
  4. "B": [1.0, 2.0, 3.0],
  5. "C": ["test1", "test2", "test3"],
  6. "D": pd.date_range("20211101", periods=3),
  7. }
  8. )
  9. df.agg(["min", "sum"])

output

  1. A B C D
  2. min 1 1.0 test1 2021-11-01
  3. sum 6 6.0 test1test2test3 NaT

出来的结果可能并非是用户所想要的了,而至于transform()方法,其效果和用法都和agg()方法及其的相似,这边也就不多做赘述

索引和列名的重命名

针对索引和列名的重命名,我们可以通过pandas当中的rename()方法来实现,例如我们有这样一个数据集

  1. df1 = pd.DataFrame(np.random.randn(5, 3), columns=["A", "B", "C"],
  2. index = ["a", "b", "c", "d", "e"])

output

  1. A B C
  2. a 0.343690 0.869984 -1.929814
  3. b 1.025613 0.470155 -0.242463
  4. c -0.400908 -0.362684 0.226857
  5. d -1.339706 -0.302005 -1.784452
  6. e -0.957026 -0.813600 0.215098

我们可以这样来操作

  1. df1.rename(columns={"A": "one", "B": "two", "C": "three"},
  2. index={"a": "apple", "b": "banana", "c": "cat"})

output

  1. one two three
  2. apple 0.383813 0.588964 -0.162386
  3. banana -0.462068 -2.938896 0.935492
  4. cat -0.059807 -1.987281 0.095432
  5. d -0.085230 2.013733 -1.324039
  6. e -0.678352 0.306776 0.808697

当然我们可以拆开来,单独对行或者是列进行重命名,对列的重命名可以这么来做

  1. df1.rename({"A": "one", "B": "two", "C": "three"}, axis = "columns")

output

  1. one two three
  2. a -0.997108 -1.383011 0.474298
  3. b 1.009910 0.286303 1.120783
  4. c 1.130700 -0.566922 1.841451
  5. d -0.350438 -0.171079 -0.079804
  6. e 0.988050 -0.524604 0.653306

对行的重命名则可以这么来做

  1. df1.rename({"a": "apple", "b": "banana", "c": "cat"}, axis = "index")

output

  1. A B C
  2. apple 0.590589 -0.311803 -0.782117
  3. banana 1.528043 -0.944476 -0.337584
  4. cat 1.326057 -0.087368 0.041444
  5. d 1.079768 -0.098314 -0.210999
  6. e 1.654869 1.170333 0.506194

排序

pandas当中,我们可以针对数据集当中的值来进行排序

  1. df1 = pd.DataFrame(
  2. {"one": [2, 1, 1, 1], "two": [1, 3, 2, 4], "three": [5, 4, 3, 2]}
  3. )

output

  1. one two three
  2. 0 2 1 5
  3. 1 1 3 4
  4. 2 1 2 3
  5. 3 1 4 2

我们按照“three”这一列当中的数值来进行排序

  1. df1.sort_values(by = "three")

output

  1. one two three
  2. 3 1 4 2
  3. 2 1 2 3
  4. 1 1 3 4
  5. 0 2 1 5

我们也可以依照多列进行排序

  1. df1.sort_values(by = ["one", "two"])

output

  1. one two three
  2. 2 1 2 3
  3. 1 1 3 4
  4. 3 1 4 2
  5. 0 2 1 5

在“one”这一列相等的时候,比较“two”这一列数值的大小,在排序的过程当中,默认采用的都是升序,我们可以改成降序来进行编排

  1. df1.sort_values("two", ascending=False)

output

  1. one two three
  2. 3 1 4 2
  3. 1 1 3 4
  4. 2 1 2 3
  5. 0 2 1 5

数据类型的转换

最后涉及到的是数据类型的转换,在这之前,我们先得知道如何来查看数据的类型,pandas当中有相应的方法可以处理

  1. df2 = pd.DataFrame(
  2. {
  3. "A": pd.Series(np.random.randn(5), dtype="float16"),
  4. "B": pd.Series(np.random.randn(5)),
  5. "C": pd.Series(np.array(np.random.randn(5), dtype="uint8")),
  6. }
  7. )

output

  1. A B C
  2. 0 -0.498779 -0.501512 0
  3. 1 -0.055817 -0.528227 254
  4. 2 -0.914551 0.763298 1
  5. 3 -0.916016 1.366833 0
  6. 4 1.993164 1.834457 0

我们通过dtypes属性来查看数据的类型

  1. A float16
  2. B float64
  3. C uint8
  4. dtype: object

而通过astype()方法来实现数据类型的转换

  1. df2["B"].astype("int64")

output

  1. 0 0
  2. 1 0
  3. 2 0
  4. 3 2
  5. 4 1
  6. Name: B, dtype: int64

根据数据类型来筛选

与此同时,我们也可以根据相对应的数据类型来进行筛选,运用pandas当中的select_dtypes方法,我们先来创建一个数据集包含了各种数据类型的

  1. df = pd.DataFrame(
  2. {
  3. "string_1": list("abcde"),
  4. "int64_1": list(range(1, 6)),
  5. "uint8_1": np.arange(3, 8).astype("u1"),
  6. "float64_1": np.arange(4.0, 9.0),
  7. "bool1": [True, False, True, True, False],
  8. "bool2": [False, True, False, False, True],
  9. "dates_1": pd.date_range("now", periods=5),
  10. "category_1": pd.Series(list("ABCDE")).astype("category"),
  11. }
  12. )

output

  1. string_1 int64_1 uint8_1 ... bool2 dates_1 category_1
  2. 0 a 1 3 ... False 2021-11-10 10:43:05.957685 A
  3. 1 b 2 4 ... True 2021-11-11 10:43:05.957685 B
  4. 2 c 3 5 ... False 2021-11-12 10:43:05.957685 C
  5. 3 d 4 6 ... False 2021-11-13 10:43:05.957685 D
  6. 4 e 5 7 ... True 2021-11-14 10:43:05.957685 E

我们先来查看一下各个列的数据类型

  1. df.dtypes

output

  1. string_1 object
  2. int64_1 int64
  3. uint8_1 uint8
  4. float64_1 float64
  5. bool1 bool
  6. bool2 bool
  7. dates_1 datetime64[ns]
  8. category_1 category
  9. dtype: object

我们筛选类型为布尔值的数据

  1. df.select_dtypes(include=[bool])

output

  1. bool1 bool2
  2. 0 True False
  3. 1 False True
  4. 2 True False
  5. 3 True False
  6. 4 False True

筛选出数据类型为整型的数据

  1. df.select_dtypes(include=['int64'])

output

  1. int64_1
  2. 0 1
  3. 1 2
  4. 2 3
  5. 3 4
  6. 4 5
技术交流

欢迎转载、收藏、有所收获点赞支持一下!

目前开通了技术交流群,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友

  • 方式①、发送如下图片至微信,长按识别,后台回复:加群;
  • 方式②、添加微信号:dkl88191,备注:来自CSDN
  • 方式③、微信搜索公众号:Python学习与数据挖掘,后台回复:加群

相关文章