python–pandas学习总结

一、Series和DataFrame

1. pandas.Series

2. pandas.DataFrame

二、Pandas常见用法

1. 访问数据

1.1 head()和tail()

1.2 describe()

1.3 T

1.4 sort_values()

1.5 nlargest()

1.6 sample()

2. 选择数据

2.1 根据标签选择

2.2 根据位置选择

2.3 布尔索引

3. 处理缺失值

3.1 dropna()

3.2 fillna()

4. 操作方法

4.1 agg()

4.2 apply()

4.3 value_counts()

4.4 str

5. 合并

5.1 concat()

5.2 merge()

6. 分组GroupBy

6.1 单列分组

6.2 多列分组

6.3 应用多聚合方法

6.4 不同列进行不同聚合统计

6.5 更多

三、Pandas 进阶用法

1. reshape

1.1 stack() 和 unstack()

1.2 pivot_table()

2. 时间序列

3. 分类

4. IO

Pandas特别适合处理表格数据,如SQL表格、EXCEL表格。有序或无序的时间序列。具有行和列标签的任意矩阵数据。

打开Jupyter Notebook,导入numpy和pandas开始我们的教程:

import numpy as np
import pandas as pd

1. pandas.Series

Series是带有索引的一维ndarray数组 。索引值可不唯一,但必须是可哈希的。

pd.Series([1, 3, 5, np.nan, 6, 8])

输出:

0    1.0
1    3.0
2    5.0
3    NaN
4    6.0
5    8.0
dtype: float64

我们可以看到默认索引值为0、1、2、3、4、5这样的数字。添加 index属性,指定其为’c’,’a’,’i’,’yong’,’j’,’i’。

pd.Series([1, 3, 5, np.nan, 6, 8], index=['c','a','i','yong','j','i'])

输出如下,我们可以看到index是可重复的。

c       1.0
a       3.0
i       5.0
yong    NaN
j       6.0
i       8.0
dtype: float64

2. pandas.DataFrame

DataFrame是带有行和列的表格结构。可以理解为多个Series对象的字典结构。

pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), index=['i','ii','iii'], columns=['A', 'B', 'C'])

输出表格如下, 其中 index 对应它的行, columns 对应它的列

ABCi123ii456iii789

1. 访问数据

准备数据,随机生成6行4列的二维数组,行标签为从20210101到20210106的日期,列标签为A、B、C、D。

import numpy as np
import pandas as pd
np.random.seed(20201212)
df = pd.DataFrame(np.random.randn(6, 4), index=pd.date_range('20210101', periods=6), columns=list('ABCD'))
df

记住 np.random.randn(6,4)的用法。 pd.date_range(“开始时间”,periods= 数量),columns = list(列字符串组合起来)

展示表格如下:

ABCD2021-01-010.270961-0.4054630.3483730.8285722021-01-020.6965410.136352-1.64592-0.698412021-01-030.325415-0.602236-0.1345081.281212021-01-04-0.33032-1.40384-0.938091.488042021-01-050.3487081.271750.626011-0.2538452021-01-06-0.8160641.301970.656281-1.2718

查看表格前几行使用head()

df.head(2)

展示表格如下:

ABCD2021-01-010.270961-0.4054630.3483730.8285722021-01-020.6965410.136352-1.64592-0.69841

查看表格后几行:使用tail()

df.tail(3)

展示表格如下:

ABCD2021-01-04-0.33032-1.40384-0.938091.488042021-01-050.3487081.271750.626011-0.2538452021-01-06-0.8160641.301970.656281-1.2718

describe方法用于生成DataFrame的描述统计信息 。可以很方便的查看数据集的分布情况

。注意,这里的统计分布不包含 NaN值 。

df.describe()

展示如下:

ABCDcount6666mean0.08254020.0497552-0.1813090.22896std0.5514121.078340.9331551.13114min-0.816064-1.40384-1.64592-1.271825%-0.18-0.553043-0.737194-0.58726950%0.298188-0.1345550.1069330.28736375%0.3428850.9879010.5566011.16805max0.6965411.301970.6562811.48804

我们首先回顾一下我们掌握的数学公式。

平均数(mean)

方差(variance):

标准差(std):

我们解释一下pandas的describe统计信息各属性的意义。我们仅以 A 列为例。

  • count 表示计数。A列有6个数据不为空。
  • mean 表示平均值。A列所有不为空的数据平均值为0.0825402。
  • std 表示标准差。A列的标准差为0.551412。
  • min 表示最小值。A列最小值为-0.816064。即,0%的数据比-0.816064小。
  • 25%表示四分之一分位数。A列的四分之一分位数为-0.18。即,25%的数据比-0.18小。
  • 50%表示二分之一分位数。A列的四分之一分位数为0.298188。即,50%的数据比0.298188小。
  • 75%表示四分之三分位数。A列的四分之三分位数为0.342885。即,75%的数据比0.342885小。
  • max表示最大值。A列的最大值为0.696541。即,100%的数据比0.696541小。

T 一般表示 Transpose 的缩写,即转置。行列转换。

df.T

展示表格如下:

2021-01-012021-01-022021-01-032021-01-042021-01-052021-01-06A0.2709610.6965410.325415-0.330320.348708-0.816064B-0.4054630.136352-0.602236-1.403841.271751.30197C0.348373-1.64592-0.134508-0.938090.6260110.656281D0.828572-0.698411.281211.48804-0.253845-1.2718

指定某一列进行排序,如下代码根据 C 列进行正序排序。其他列随着移动

df.sort_values(by='C')

展示表格如下:

ABCD2021-01-020.6965410.136352-1.64592-0.698412021-01-04-0.33032-1.40384-0.938091.488042021-01-030.325415-0.602236-0.1345081.281212021-01-010.270961-0.4054630.3483730.8285722021-01-050.3487081.271750.626011-0.2538452021-01-06-0.8160641.301970.656281-1.2718

选择某列最大的n行数据。如: df.nlargest(2,'A') 表示,返回A列最大的2行数据。

df.nlargest(2,'A')

展示表格如下:

ABCD2021-01-020.6965410.136352-1.64592-0.698412021-01-050.3487081.271750.626011-0.253845

sample 方法表示查看随机的样例数据。

df.sample(5)表示返回随机5行数据 。

df.sample(5)

参数 frac 表示fraction,分数的意思。frac=0.01即返回1%的随机数据作为样例展示。

df.sample(frac=0.01)

2. 选择数据

我们输入 df['A']命令选取A列。

df['A']

输出A列数据,同时也是一个Series对象:

2021-01-01    0.270961
2021-01-02    0.696541
2021-01-03    0.325415
2021-01-04   -0.330320
2021-01-05    0.348708
2021-01-06   -0.816064
Name: A, dtype: float64

df[0:3]该代码与 df.head(3)同理。但 df[0:3]是NumPy的数组选择方式,这说明了Pandas对于NumPy具有良好的支持。

df[0:3]

展示表格如下:

ABCD2021-01-010.270961-0.4054630.3483730.8285722021-01-020.6965410.136352-1.64592-0.698412021-01-030.325415-0.602236-0.1345081.28121

通过loc方法指定行列标签。

df.loc['2021-01-01':'2021-01-02', ['A', 'B']]

展示表格如下:

AB2021-01-010.270961-0.4054632021-01-020.6965410.136352

ilocloc 不同。 loc 指定具体的标签,而 iloc 指定标签的索引位置。

df.iloc[3:5, 0:3]表示选取索引为3、4的行,索引为0、1、2的列。

即,第4、5行,第1、2、3列。注意,索引序号从0开始。

冒号表示区间,左右两侧分别表示开始和结束。

3:5 表示左开右闭区间 [3,5) ,即不包含5自身。

df.iloc[3:5, 0:3]

ABC2021-01-04-0.33032-1.40384-0.938092021-01-050.3487081.271750.626011

df.iloc[:, 1:3]

BC2021-01-01-0.4054630.3483732021-01-020.136352-1.645922021-01-03-0.602236-0.1345082021-01-04-1.40384-0.938092021-01-051.271750.6260112021-01-061.301970.656281

DataFrame可根据条件进行筛选,当条件判断 True时,返回。当条件判断为 False时,过滤掉。

我们设置一个过滤器用来判断A列是否大于0。

filter = df['A'] > 0
filter

输出结果如下,可以看到 2021-01-042021-01-06的行为False。

2021-01-01     True
2021-01-02     True
2021-01-03     True
2021-01-04    False
2021-01-05     True
2021-01-06    False
Name: A, dtype: bool

我们通过过滤器查看数据集。

df[filter]
# df[df['A'] > 0]

查看表格我们可以发现, 2021-01-042021-01-06的行被过滤掉了。

ABCD2021-01-010.270961-0.4054630.3483730.8285722021-01-020.6965410.136352-1.64592-0.698412021-01-030.325415-0.602236-0.1345081.281212021-01-050.3487081.271750.626011-0.253845

3. 处理缺失值

准备数据。

DataFrame添加一列

df3[“新的列名”]= 内容

df3=df.copy()
df3.loc[:3,'E']=1.0
#f_series={'2021-01-02':1.0,'2021-01-03':2.0,'2021-01-04':3.0,'2021-01-05':4.0,'2021-01-06':5.0}
f_series=[9.0,1.0,2.0,3.0,4.0,5.0]
#df3['F']=pd.Series(f_series)
df3["F"] = ([0,1.0,2.0,3.0,4.0,5.0])
print(df3)

展示表格如下:

ABCDFE2021-01-010.270961-0.4054630.3483730.828572nan12021-01-020.6965410.136352-1.64592-0.69841112021-01-030.325415-0.602236-0.1345081.28121212021-01-04-0.33032-1.40384-0.938091.488043nan2021-01-050.3487081.271750.626011-0.2538454nan2021-01-06-0.8160641.301970.656281-1.27185nan

使用dropna方法清空NaN值。

注意:dropa方法返回新的DataFrame,并不会改变原有的DataFrame。

df2.dropna(how='any')

以上代码表示,当行数据有任意的数值为空时,删除。

ABCDFE2021-01-020.6965410.136352-1.64592-0.69841112021-01-030.325415-0.602236-0.1345081.2812121

使用filna命令填补NaN值。

df2.fillna(df2.mean())

以上代码表示,使用每一列的平均值来填补空缺

同样地,fillna并不会更新原有的DataFrame,如需更新原有DataFrame使用代码 df2 = df2.fillna(df2.mean())

展示表格如下:

ABCDFE2021-01-010.270961-0.4054630.3483730.828572312021-01-020.6965410.136352-1.64592-0.69841112021-01-030.325415-0.602236-0.1345081.28121212021-01-04-0.33032-1.40384-0.938091.48804312021-01-050.3487081.271750.626011-0.253845412021-01-06-0.8160641.301970.656281-1.271851

4. 操作方法

agg是Aggregate的缩写,意为聚合。

常用聚合方法如下:

  • mean(): Compute mean of groups
  • sum(): Compute sum of group values
  • size(): Compute group sizes
  • count(): Compute count of group
  • std(): Standard deviation of groups
  • var(): Compute variance of groups
  • sem(): Standard error of the mean of groups
  • describe(): Generates descriptive statistics
  • first(): Compute first of group values
  • last(): Compute last of group values
  • nth() : Take nth value, or a subset if n is a list
  • min(): Compute min of group values
  • *max(): Compute max of group values
df.mean()

返回各列平均值 df.mean():返回各列平均值

A    0.082540
B    0.049755
C   -0.181309
D    0.228960
dtype: float64

可通过加参数axis查看行平均值。

df.mean(axis=1)

输出:

2021-01-01    0.260611
2021-01-02   -0.377860
2021-01-03    0.217470
2021-01-04   -0.296053
2021-01-05    0.498156
2021-01-06   -0.032404
dtype: float64

如果我们想查看某一列的多项聚合统计怎么办?
这时我们可以调用agg方法:df.agg([“某个统计量”,”某个统计量”])[某列索引]

df.agg(['std','mean'])['A']

返回结果显示标准差std和均值mean:

std     0.551412
mean    0.082540
Name: A, dtype: float64

对于不同的列应用不同的聚合函数df.agg({‘A’:[‘max’,’mean’],’B’:[‘mean’,’std’,’var’]})

df.agg({'A':['max','mean'],'B':['mean','std','var']})

返回结果如下:

ABmax0.696541nanmean0.08254020.0497552stdnan1.07834varnan1.16281

apply()是对方法的调用。

df.apply(np.sum)表示每一列调用np.sum方法, 返回每一列的数值和。

df.apply(np.sum)

输出结果为:

A    0.495241
B    0.298531
C   -1.087857
D    1.373762
dtype: float64

apply方法支持lambda表达式。

df.apply(lambda n: n*2)

ABCD2021-01-010.541923-0.8109250.6967471.657142021-01-021.393080.272704-3.29185-1.396822021-01-030.65083-1.20447-0.2690162.562422021-01-04-0.66064-2.80768-1.876182.976072021-01-050.6974172.54351.25202-0.507692021-01-06-1.632132.603931.31256-2.5436

value_counts方法查看各行、列的数值重复统计。

我们重新生成一些整数数据,来保证有一定的数据重复。

np.random.seed(101)
df3 = pd.DataFrame(np.random.randint(0,9,size = (6,4)),columns=list('ABCD'))
df3

ABCD016781485025813383324837057843

调用value_counts()方法。统计每个值出现的次数

df3['A'].value_counts()

查看输出我们可以看到 A列的数字8有两个,其他数字的数量为1。

8    2
7    1
5    1
4    1
1    1
Name: A, dtype: int64

Pandas内置字符串处理方法。

names = pd.Series(['andrew','bobo','claire','david','4'])
names.str.upper()

通过以上代码我们将 Series中的字符串全部设置为大写:names.str.upper()

0    ANDREW
1      BOBO
2    CLAIRE
3     DAVID
4         4
dtype: object

首字母大写:names.str.capitalize()

names.str.capitalize()

输出为:

0    Andrew
1      Bobo
2    Claire
3     David
4         4
dtype: object

判断是否为数字:names.str.isdigit()

names.str.isdigit()

输出为:

0    False
1    False
2    False
3    False
4     True
dtype: bool

字符串分割:

tech_finance = ['GOOG,APPL,AMZN','JPM,BAC,GS']
tickers = pd.Series(tech_finance)
tickers.str.split(',').str[0:2]

以逗号分割字符串,结果为:

0    [GOOG, APPL]
1      [JPM, BAC]
dtype: object

5. 合并

concat用来将数据集串联起来。我们先准备数据。

data_one = {'Col1': ['A0', 'A1', 'A2', 'A3'],'Col2': ['B0', 'B1', 'B2', 'B3']}
data_two = {'Col1': ['C0', 'C1', 'C2', 'C3'], 'Col2': ['D0', 'D1', 'D2', 'D3']}
one = pd.DataFrame(data_one)
two = pd.DataFrame(data_two)

使用concat方法将两个数据集串联起来。pd.concat([one,two])

print(pd.concat([one,two]))

得到表格:

Col1Col20A0B01A1B12A2B23A3B30C0D01C1D12C2D23C3D3

merge相当于SQL操作中的join方法,用于将两个数据集通过某种关系连接起来

registrations = pd.DataFrame({'reg_id':[1,2,3,4],'name':['Andrew','Bobo','Claire','David']})
logins = pd.DataFrame({'log_id':[1,2,3,4],'name':['Xavier','Andrew','Yolanda','Bobo']})

我们根据 name来连接两个张表,连接方式为 outer

pd.merge(left=registrations, right=logins, how='outer',on='name')

返回结果为:

reg_idnamelog_id01Andrew212Bobo423Clairenan34Davidnan4nanXavier15nanYolanda3

我们注意, how : {‘left’, ‘right’, ‘outer’, ‘inner’}有4种连接方式。

表示是否选取左右两侧表的nan值。如left表示保留左侧表中所有数据,

当遇到右侧表数据为nan值时,不显示右侧的数据。简单来说,把left表和right表看作两个集合。

  • left表示取左表全部集合+两表交集
  • right表示取右表全部集合+两表交集
  • outer表示取两表并集
  • *inner表示取两表交集

6. 分组GroupBy

Pandas中的分组功能非常类似于SQL语句 SELECT Column1, Column2, mean(Column3),

sum(Column4)FROM SomeTableGROUP BY Column1, Column2

即使没有接触过SQL也没有关系,分组就相当于把表格数据按照某一列进行拆分、统计、合并的过程。

准备数据。

np.random.seed(20201212)
df = pd.DataFrame({'A': ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
                   'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
                   'C': np.random.randn(8),
                   'D': np.random.randn(8)})
df

可以看到,我们的A列和B列有很多重复数据。这时我们可以根据foo/bar或者one/two进行分组。

ABCD0fooone0.2709610.3254151barone-0.405463-0.6022362footwo0.348373-0.1345083barthree0.8285721.281214footwo0.696541-0.330325bartwo0.136352-1.403846fooone-1.64592-0.938097foothree-0.698411.48804

我们应用 groupby方法将上方表格中的数据进行分组。

df.groupby('A')

执行上方代码可以看到,groupby方法返回的是一个类型为 DataFrameGroupBy的对象。我们无法直接查看,需要应用聚合函数。参考本文4.1节。

<pandas.core.groupby.generic.dataframegroupby object at 0x0000014c6742e248>
</pandas.core.groupby.generic.dataframegroupby object at 0x0000014c6742e248>

我们应用聚合函数sum试试

df.groupby('A').sum()

展示表格如下:

ACDbar0.559461-0.724868foo-1.028460.410533

groupby 方法支持将多个列作为参数传入。

df.groupby(['A',&#xA0;'B']).sum()

分组后显示结果如下:

ABCDbarone-0.405463-0.602236 one-0.405463-0.602236 three0.8285721.28121 two0.136352-1.40384fooone-1.37496-0.612675 three-0.698411.48804 two1.04491-0.464828

我们应用 agg() ,将聚合方法数组作为参数传入方法。

下方代码根据A分类且只统计 C列的数值。

df.groupby('A')['C'].agg([np.sum,&#xA0;np.mean,&#xA0;np.std])

可以看到bar组与foo组各聚合函数的结果如下:

Asummeanstdbar0.5594610.1864870.618543foo-1.02846-0.2056920.957242

下方代码对C、D列分别进行不同的聚合统计,对C列进行求和,对D列进行标准差统计。

df.groupby('A').agg({'C':&#xA0;'sum',&#xA0;'D':&#xA0;lambda&#xA0;x:&#xA0;np.std(x,&#xA0;ddof=1)})

输出如下:

ACDbar0.5594611.37837foo-1.028460.907422

更多关于Pandas的 goupby方法请参考官网: Pandas User Guide – groupby

Pandas User Guide – groupby: https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html](https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html

1. reshape

reshape 表示重塑表格。

对于复杂表格,我们需要将其转换成适合我们理解的样子,比如根据某些属性分组后进行单独统计。

stack 方法将表格分为索引和数据两个部分。索引各列保留,数据堆叠放置。

准备数据。

tuples&#xA0;=&#xA0;list(zip(*[['bar',&#xA0;'bar',&#xA0;'baz',&#xA0;'baz','foo',&#xA0;'foo',&#xA0;'qux',&#xA0;'qux'],
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;['one',&#xA0;'two',&#xA0;'one',&#xA0;'two','one',&#xA0;'two',&#xA0;'one',&#xA0;'two']]))
index&#xA0;=&#xA0;pd.MultiIndex.from_tuples(tuples,&#xA0;names=['first',&#xA0;'second'])

根据上方代码,我们创建了一个复合索引。

MultiIndex([('bar',&#xA0;'one'),
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;('bar',&#xA0;'two'),
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;('baz',&#xA0;'one'),
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;('baz',&#xA0;'two'),
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;('foo',&#xA0;'one'),
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;('foo',&#xA0;'two'),
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;('qux',&#xA0;'one'),
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;('qux',&#xA0;'two')],
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;names=['first',&#xA0;'second'])

我们创建一个具备复合索引的DataFrame。

np.random.seed(20201212)
df&#xA0;=&#xA0;pd.DataFrame(np.random.randn(8,&#xA0;2),&#xA0;index=index,&#xA0;columns=['A',&#xA0;'B'])
df

输出如下:

ABCDbarone0.270961-0.405463 two0.3483730.828572bazone0.6965410.136352 two-1.64592-0.69841fooone0.325415-0.602236 two-0.1345081.28121quxone-0.33032-1.40384 two-0.938091.48804

我们执行 stack方法。

stacked&#xA0;=&#xA0;df.stack()
stacked

输出堆叠(压缩)后的表格如下。 注意:你使用Jupyter Notebook/Lab进行的输出可能和如下结果不太一样。下方输出的各位为了方便在Markdown中显示有一定的调整。

first&#xA0;&#xA0;second&#xA0;&#xA0;&#xA0;
bar&#xA0;&#xA0;&#xA0;&#xA0;one&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;A&#xA0;&#xA0;&#xA0;&#xA0;0.942502
bar&#xA0;&#xA0;&#xA0;&#xA0;one&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;B&#xA0;&#xA0;&#xA0;&#xA0;0.060742
bar&#xA0;&#xA0;&#xA0;&#xA0;two&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;A&#xA0;&#xA0;&#xA0;&#xA0;1.340975
bar&#xA0;&#xA0;&#xA0;&#xA0;two&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;B&#xA0;&#xA0;&#xA0;-1.712152
baz&#xA0;&#xA0;&#xA0;&#xA0;one&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;A&#xA0;&#xA0;&#xA0;&#xA0;1.899275
baz&#xA0;&#xA0;&#xA0;&#xA0;one&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;B&#xA0;&#xA0;&#xA0;&#xA0;1.237799
baz&#xA0;&#xA0;&#xA0;&#xA0;two&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;A&#xA0;&#xA0;&#xA0;-1.589069
baz&#xA0;&#xA0;&#xA0;&#xA0;two&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;B&#xA0;&#xA0;&#xA0;&#xA0;1.288342
foo&#xA0;&#xA0;&#xA0;&#xA0;one&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;A&#xA0;&#xA0;&#xA0;-0.326792
foo&#xA0;&#xA0;&#xA0;&#xA0;one&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;B&#xA0;&#xA0;&#xA0;&#xA0;1.576351
foo&#xA0;&#xA0;&#xA0;&#xA0;two&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;A&#xA0;&#xA0;&#xA0;&#xA0;1.526528
foo&#xA0;&#xA0;&#xA0;&#xA0;two&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;B&#xA0;&#xA0;&#xA0;&#xA0;1.410695
qux&#xA0;&#xA0;&#xA0;&#xA0;one&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;A&#xA0;&#xA0;&#xA0;&#xA0;0.420718
qux&#xA0;&#xA0;&#xA0;&#xA0;one&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;B&#xA0;&#xA0;&#xA0;-0.288002
qux&#xA0;&#xA0;&#xA0;&#xA0;two&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;A&#xA0;&#xA0;&#xA0;&#xA0;0.361586
qux&#xA0;&#xA0;&#xA0;&#xA0;two&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;B&#xA0;&#xA0;&#xA0;&#xA0;0.177352
dtype:&#xA0;float64

我们执行unstack将数据进行展开。

stacked.unstack()

输出原表格。

ABCDbarone0.270961-0.405463 two0.3483730.828572bazone0.6965410.136352 two-1.64592-0.69841fooone0.325415-0.602236 two-0.1345081.28121quxone-0.33032-1.40384 two-0.938091.48804

我们加入参数 level

stacked.unstack(level=0)
#stacked.unstack(level=1)

level=0时得到如下输出,大家可以试试 level=1时输出什么。

secondfirstbarbazfooquxoneA0.9425021.89927-0.3267920.420718oneB0.0607421.23781.57635-0.288002twoA1.34097-1.589071.526530.361586twoB-1.712151.288341.41070.177352

pivot_table表示透视表,是一种对数据动态排布并且分类汇总的表格格式。

我们生成无索引列的DataFrame。

np.random.seed(99)
df&#xA0;=&#xA0;pd.DataFrame({'A':&#xA0;['one',&#xA0;'one',&#xA0;'two',&#xA0;'three']&#xA0;*&#xA0;3,
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;'B':&#xA0;['A',&#xA0;'B',&#xA0;'C']&#xA0;*&#xA0;4,
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;'C':&#xA0;['foo',&#xA0;'foo',&#xA0;'foo',&#xA0;'bar',&#xA0;'bar',&#xA0;'bar']&#xA0;*&#xA0;2,
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;'D':&#xA0;np.random.randn(12),
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;'E':&#xA0;np.random.randn(12)})
df

展示表格如下:

ABCDE0oneAfoo-0.1423590.02350011oneBfoo2.057220.4562012twoCfoo0.2832620.2704933threeAbar1.32981-1.435014oneBbar-0.1546220.8828175oneCbar-0.0690309-0.5800826twoAfoo0.75518-0.5015657threeBfoo0.8256470.5909538oneCfoo-0.113069-0.7316169oneAbar-2.367840.26175510twoBbar-0.167049-0.85579611threeCbar0.685398-0.187526

通过观察数据,我们可以显然得出A、B、C列的具备一定属性含义。我们执行 pivot_table方法。

pd.pivot_table(df,&#xA0;values=['D','E'],&#xA0;index=['A',&#xA0;'B'],&#xA0;columns=['C'])

上方代码的意思为,将D、E列作为数据列,A、B作为复合行索引, C的数据值作为列索引。

(‘D’, ‘bar’)(‘D’, ‘foo’)(‘E’, ‘bar’)(‘E’, ‘foo’)(‘one’, ‘A’)-2.36784-0.1423590.2617550.0235001(‘one’, ‘B’)-0.1546222.057220.8828170.456201(‘one’, ‘C’)-0.0690309-0.113069-0.580082-0.731616(‘three’, ‘A’)1.32981nan-1.43501nan(‘three’, ‘B’)nan0.825647nan0.590953(‘three’, ‘C’)0.685398nan-0.187526nan(‘two’, ‘A’)nan0.75518nan-0.501565(‘two’, ‘B’)-0.167049nan-0.855796nan(‘two’, ‘C’)nan0.283262nan0.270493

2. 时间序列

date_range是Pandas自带的生成日期间隔的方法。我们执行下方代码:

rng&#xA0;=&#xA0;pd.date_range('1/1/2021',&#xA0;periods=100,&#xA0;freq='S')
pd.Series(np.random.randint(0,&#xA0;500,&#xA0;len(rng)),&#xA0;index=rng)

date_range方法从2021年1月1日0秒开始,以1秒作为时间间隔执行100次时间段的划分。输出结果如下:

2021-01-01&#xA0;00:00:00&#xA0;&#xA0;&#xA0;&#xA0;475
2021-01-01&#xA0;00:00:01&#xA0;&#xA0;&#xA0;&#xA0;145
2021-01-01&#xA0;00:00:02&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;13
2021-01-01&#xA0;00:00:03&#xA0;&#xA0;&#xA0;&#xA0;240
2021-01-01&#xA0;00:00:04&#xA0;&#xA0;&#xA0;&#xA0;183
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;...&#xA0;
2021-01-01&#xA0;00:01:35&#xA0;&#xA0;&#xA0;&#xA0;413
2021-01-01&#xA0;00:01:36&#xA0;&#xA0;&#xA0;&#xA0;330
2021-01-01&#xA0;00:01:37&#xA0;&#xA0;&#xA0;&#xA0;272
2021-01-01&#xA0;00:01:38&#xA0;&#xA0;&#xA0;&#xA0;304
2021-01-01&#xA0;00:01:39&#xA0;&#xA0;&#xA0;&#xA0;151
Freq:&#xA0;S,&#xA0;Length:&#xA0;100,&#xA0;dtype:&#xA0;int32

我们 freq 的参数值从S(second)改为M(Month)试试看。

rng&#xA0;=&#xA0;pd.date_range('1/1/2021',&#xA0;periods=100,&#xA0;freq='M')
pd.Series(np.random.randint(0,&#xA0;500,&#xA0;len(rng)),&#xA0;index=rng)

输出:

2021-01-31&#xA0;&#xA0;&#xA0;&#xA0;311
2021-02-28&#xA0;&#xA0;&#xA0;&#xA0;256
2021-03-31&#xA0;&#xA0;&#xA0;&#xA0;327
2021-04-30&#xA0;&#xA0;&#xA0;&#xA0;151
2021-05-31&#xA0;&#xA0;&#xA0;&#xA0;484
&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;...&#xA0;
2028-12-31&#xA0;&#xA0;&#xA0;&#xA0;170
2029-01-31&#xA0;&#xA0;&#xA0;&#xA0;492
2029-02-28&#xA0;&#xA0;&#xA0;&#xA0;205
2029-03-31&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;90
2029-04-30&#xA0;&#xA0;&#xA0;&#xA0;446
Freq:&#xA0;M,&#xA0;Length:&#xA0;100,&#xA0;dtype:&#xA0;int32

我们设置可以以季度作为频率进行日期生成。

prng&#xA0;=&#xA0;pd.period_range('2018Q1',&#xA0;'2020Q4',&#xA0;freq='Q-NOV')
pd.Series(np.random.randn(len(prng)),&#xA0;prng)

输出2018第一季度到2020第四季度间的全部季度。

2018Q1&#xA0;&#xA0;&#xA0;&#xA0;0.833025
2018Q2&#xA0;&#xA0;&#xA0;-0.509514
2018Q3&#xA0;&#xA0;&#xA0;-0.735542
2018Q4&#xA0;&#xA0;&#xA0;-0.224403
2019Q1&#xA0;&#xA0;&#xA0;-0.119709
2019Q2&#xA0;&#xA0;&#xA0;-1.379413
2019Q3&#xA0;&#xA0;&#xA0;&#xA0;0.871741
2019Q4&#xA0;&#xA0;&#xA0;&#xA0;0.877493
2020Q1&#xA0;&#xA0;&#xA0;&#xA0;0.577611
2020Q2&#xA0;&#xA0;&#xA0;-0.365737
2020Q3&#xA0;&#xA0;&#xA0;-0.473404
2020Q4&#xA0;&#xA0;&#xA0;&#xA0;0.529800
Freq:&#xA0;Q-NOV,&#xA0;dtype:&#xA0;float64

3. 分类

Pandas有一种特殊的数据类型叫做”目录”,即dtype=”category”,我们根据将某些列设置为目录来进行分类

准备数据。

df&#xA0;=&#xA0;pd.DataFrame({"id":&#xA0;[1,&#xA0;2,&#xA0;3,&#xA0;4,&#xA0;5,&#xA0;6],&#xA0;"raw_grade":&#xA0;['a',&#xA0;'b',&#xA0;'b',&#xA0;'a',&#xA0;'a',&#xA0;'e']})
df

idraw_grade01a12b23b34a45a56e

我们添加一个新列 grade 并将它的数据类型设置为 category

df["grade"]&#xA0;=&#xA0;df["raw_grade"].astype("category")
df["grade"]

我们可以看到 grade列只有3种值a,b,e。

0&#xA0;&#xA0;&#xA0;&#xA0;a
1&#xA0;&#xA0;&#xA0;&#xA0;b
2&#xA0;&#xA0;&#xA0;&#xA0;b
3&#xA0;&#xA0;&#xA0;&#xA0;a
4&#xA0;&#xA0;&#xA0;&#xA0;a
5&#xA0;&#xA0;&#xA0;&#xA0;e
Name:&#xA0;grade,&#xA0;dtype:&#xA0;category
Categories&#xA0;(3,&#xA0;object):&#xA0;['a',&#xA0;'b',&#xA0;'e']

我们按顺序替换a、b、e为very good、good、very bad。

df["grade"].cat.categories&#xA0;=&#xA0;["very&#xA0;good",&#xA0;"good",&#xA0;"very&#xA0;bad"]

此时的表格为:

idraw_gradegrade01avery good12bgood23bgood34avery good45avery good56every bad

我们对表格进行排序:

df.sort_values(by="grade",&#xA0;ascending=False)

idraw_gradegrade56every bad12bgood23bgood01avery good34avery good45avery good

查看各类别的数量:

df.groupby("grade").size()

以上代码输出为:

grade
very&#xA0;good&#xA0;&#xA0;&#xA0;&#xA0;3
good&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;2
very&#xA0;bad&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;1
dtype:&#xA0;int64

4. IO

Pandas支持直接从文件中读写数据,如CSV、JSON、EXCEL等文件格式。Pandas支持的文件格式如下。

Format TypeData DescriptionReaderWritertextCSVread_csvto_csvtextFixed-Width Text Fileread_fwf textJSONread_jsonto_jsontextHTMLread_htmlto_htmltextLocal clipboardread_clipboardto_clipboard MS Excelread_excelto_excelbinaryOpenDocumentread_excel binaryHDF5 Formatread_hdfto_hdfbinaryFeather Formatread_featherto_featherbinaryParquet Formatread_parquetto_parquetbinaryORC Formatread_orc binaryMsgpackread_msgpackto_msgpackbinaryStataread_statato_statabinarySASread_sas binarySPSSread_spss binaryPython Pickle Formatread_pickleto_pickleSQLSQLread_sqlto_sqlSQLGoogle BigQueryread_gbqto_gbq

我们仅以CSV文件为例作为讲解。其他格式请参考上方表格。

我们从CSV文件导入数据。 大家不用特别在意下方网址的域名地址

df&#xA0;=&#xA0;pd.read_csv("http://blog.caiyongji.com/assets/housing.csv")

查看前5行数据:

df.head(5)

longitudelatitudehousing_median_agetotal_roomstotal_bedroomspopulationhouseholdsmedian_incomemedian_house_valueocean_proximity0-122.2337.88418801293221268.3252452600NEAR BAY1-122.2237.862170991106240111388.3014358500NEAR BAY2-122.2437.855214671904961777.2574352100NEAR BAY3-122.2537.855212742355582195.6431341300NEAR BAY4-122.2537.855216272805652593.8462342200NEAR BAY

参考文献:机器学习初学者公众号。

Original: https://blog.csdn.net/yezonghui/article/details/113826802
Author: 斑马!
Title: python–pandas学习总结

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/739431/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球