Pandas常见方法(4)
声明:以下内容都是基于python3.8版本。
文章目录
- 一、pandas.DataFrame在index或column两个维度上的拓展
- 二、pandas.DataFrame的join, group,merge和numpy.concatenate方法
- 三、pandas.DataFrame的常用统计方法
- 总结
一、pandas.DataFrame在index或column两个维度上的拓展
pandas.DataFrame 做为一种数据存在类型,我们可以从index和column两个方向上对原有的pandas.DataFrame进行进一步拓展。
1.1 首先,我们考虑从column维度对pandas.DataFrame进行拓展。
基本公式:DataFrame[‘’] = (,…)
我们首先设定初始化两个pandas.DataFrame,代码如下:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#初始化DataFrame
df = pd.DataFrame([[10,20],[20,40],[30,50],[70,90],], index = ['a','b','c','d'], columns = ['number','post'])
df1 = pd.DataFrame([101,202,303,404], columns = ['number'])
print(df)
print(df1)
我们会得到df,
number post
a 10 20
b 20 40
c 30 50
d 70 90
以及df1,
number
0 101
1 202
2 303
3 404
现在我们对df新增一列ID,并赋值1.1,1.2,1.3,1.4
代码如下,
df['ID'] = (1.1,1.2,1.3,1.4)
print(df)
得到新的df,
number post ID
a 10 20 1.1
b 20 40 1.2
c 30 50 1.3
d 70 90 1.4
1.2 我们考虑从index维度对pandas.DataFrame进行拓展。
基本公式:
新DataFrame = 旧DataFrame .append(pd.DataFrame({“number”:[,…],“ID”:[,…]},index = [,…]))
易错点:一定记得储存到新的变量中!!!
我们继续沿用刚刚初始化的df,我们这次需要命名一个新的索引名,z,把df进行进一步扩充。
代码如下:
df = df.append(pd.DataFrame({"number":2.1,"ID":2.2},index = ['z']))
print(df)
结果如下,
number post ID
a 10.0 20.0 1.1
b 20.0 40.0 1.2
c 30.0 50.0 1.3
d 70.0 90.0 1.4
z 2.1 NaN 2.2
二、pandas.DataFrame的join, group,merge和numpy.concatenate方法
在进行数据的过程中,我们经常用到表的级联和分组。python的join, merge和group方法的实现原理与sql语言相差无几。但在语言表达上有些区别,需要注意。
2.1我们先来介绍一下,常见的join方法。
【重点:join只能做左右拼接,不能做上下拼接,缺失值用NAN补全;优点是可以同时拼接好几个DataFrame,且相较merge和concatenate方法速度更快】
2.1.1 join的第一种方法,先设置两个需要级联表的index(也称为索引),再级联。(默认为左级联,以主表的index作为key attribute,所有非index列的空位用null值补全,若有重名列(且不是级联列)用lsuffix和rsuffix的命名区分)
基本公式:
新pandas.DataFrame=pandas.DataFrame1.set_index().join(pandas.DataFrame2.set_index(),lsuffix=‘_caller’, rsuffix=‘_other’)
代码如下:
df2=df.set_index('number').join(df1.set_index('number'),lsuffix='_caller', rsuffix='_other')
df3=df1.set_index('number').join(df.set_index('number'),lsuffix='_caller', rsuffix='_other')
print(df2)
print(df3)
df2得到结果如下,
post ID
number
10.0 20.0 1.1
20.0 40.0 1.2
30.0 50.0 1.3
70.0 90.0 1.4
2.1 NaN 2.2
我们可以清楚看到,两个表根据number这一列进行级联,并且默认为左级联,但右表即df1的number一列值没有跟df的number相等的值存在,所以,我们得到的df2,这个新的级联表和df是一样的。
同理,我们可以得到df3表,因为df1中不存在post 和 ID 两列,但df中存在。所以,我们用null值补全空位。
df3结果如下,
post ID
number
101 NaN NaN
202 NaN NaN
303 NaN NaN
404 NaN NaN
但当df1的级联的index和df的级联的index存在相同值时,我们会得到如下级联表。
代码如下,
df.iloc[0,0] = 101
df3=df1.set_index('number').join(df.set_index('number'),lsuffix='_caller', rsuffix='_other')
print(df3)
结果如下,
post ID
number
101 20.0 1.1
202 NaN NaN
303 NaN NaN
404 NaN NaN
或者,我把df1也利用column维度进行扩充,再与df级联,我们看一下效果。
得到的新的df和df1分别为,
number post ID
a 101.0 20.0 1.1
b 20.0 40.0 1.2
c 30.0 50.0 1.3
d 70.0 90.0 1.4
z 2.1 NaN 2.2
number ID
0 101 1.1
1 202 1.2
2 303 1.5
3 404 1.3
df1['ID'] = [1.1,1.2,1.5,1.3]
df3=df1.set_index('number').join(df.set_index('number'),lsuffix='_caller', rsuffix='_other')
print(df3)
因为两个表中都存在key attribute以外的相同的column,所以我们得到加后缀的额外列。
结果如下,
ID_caller post ID_other
number
101 1.1 20.0 1.1
202 1.2 NaN NaN
303 1.5 NaN NaN
404 1.3 NaN NaN
2.1.2 join的第二种方法,直接级联。(默认为左级联,以主表的index为key attribute,所有非index 的列的空位用null值补全,若有重名列(且不是级联列)用lsuffix和rsuffix的命名区分)
基本公式:pandas.DataFrame1.join(pandas.DataFrame2, on=None,how=‘‘lsuffix=’’, rsuffix=‘’, sort=False)
得到
我们继续利用已经得到的df和df1,进行直接级联,并指定级联方式为右级联。
df4 = df.join(df1,lsuffix='_caller', rsuffix='_other',how = 'right')
print(df4)
因为这时我们并没有指定 key,所以用index作为key attribute,得到结果如下,
number_caller post ID_caller number_other ID_other
0 NaN NaN NaN 101 1.1
1 NaN NaN NaN 202 1.2
2 NaN NaN NaN 303 1.5
3 NaN NaN NaN 404 1.3
2.2 我们接下来介绍一下,group分组方法。
基本公式:pandas.DataFrame.groupby([<目标attribute 1>,<目标attribute2>…]),再按其他column做对应运算。(前提是我们可以先设置一个新列,并按分组要求对每行打上分组标签)
首先我们生成包含9行4列的标准正态分布的伪随机数ndarrage,再用DatatimeIndex作为索引,并以期末取值,代码如下,
a = np.random.standard_normal((9,4))
a = a.round(6)
df6 = pd.DataFrame(a)
#生成DatatimeIndex索引,以期末取值
dates = pd.date_range('2016-01-01','2019-12-31',freq = 'Y')
df6.columns = dates
print(df6)
输出结果如下,
2016-12-31 2017-12-31 2018-12-31 2019-12-31
0 0.453243 -0.068952 1.545494 0.510076
1 0.837713 -1.465241 -0.740922 -1.524568
2 -0.384375 1.165462 -0.273746 0.508105
3 -0.143992 -0.554521 -0.168501 1.020890
4 1.116631 0.633020 0.588792 -0.410130
5 1.824028 0.216709 1.293103 -2.147095
6 -0.085606 -0.613363 0.988932 -1.005342
7 0.463741 0.336018 0.202069 -0.609974
8 0.884615 0.164266 0.577031 0.322006
然后我们把上边表格按index分组,前8个两两一组,最后一个一组,用quarter表示。
代码如下,
df6['quator'] = (1,1,2,2,3,3,4,4,5)
最后求出每组的在每个column下的均值,代码如下,
print(df6.groupby('quator').mean())
结果如下,
2016-12-31 ... 2019-12-31
quator ...
1 -0.971370 ... -0.098655
2 0.758503 ... -0.735746
3 -0.564706 ... -0.756345
4 0.126177 ... -0.114578
5 2.081236 ... -0.433217
[5 rows x 4 columns]
2.3 我们接下来介绍一下merge方法,merge方法是翻版的sql的join方法。
【重点:merge只能做左右拼接,不能做上下拼接,缺失值用NAN补全;与join方法效果类似】
【易错点:如果左右两个DataFrame没有对应的拼接依据,则报错】
基本公式:pandas.merge(<目标pandas.DataFrame 左>,<目标pandas.DataFrame 右>,再按 left_on/right_on/on 上的列名/索引作为拼接依据,做how 上的方法作为拼接方法,包括“inner”,“outer”,“left”,"right"做对应方法拼接,默认为“inner”。另外,left_on /right_on 与 left_index/right_index 可以混合使用来确定拼接依据, 其中left_index/right_index 为True/False。最后可以使用sort=True,对拼接依据进行排序【注:从小到大】)
首先我们生成df1,df2 代码如下,
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'key': ['K0', 'K1', 'K0', 'K1']})
df2 = pd.DataFrame({'C': ['C0', 'C1'],
'D': ['D0', 'D1'],
'k':['K0', 'K1']})
print(df1)
print(df2)
输出结果如下,
A B key
0 A0 B0 K0
1 A1 B1 K1
2 A2 B2 K0
3 A3 B3 K1
C D k
0 C0 D0 K0
1 C1 D1 K1
然后我们把df1和df2左右拼接,如果我们把on 赋值为 df1 的 “B”,则会报错;
如下图
原因是df2列表没有“B”这一列名。
所以,我们以df1的“key” 和 df2的 “k”作为拼接依据,采用left方法,并根据拼接依据的值进行表格排序。
代码如下,
df3 = pd.merge(df1, df2, left_on = "key",right_on = "k", how = "left",sort = True)
print(df3)
最后得出结果,如下
A B key C D k
0 A0 B0 K0 C0 D0 K0
1 A2 B2 K0 C0 D0 K0
2 A1 B1 K1 C1 D1 K1
3 A3 B3 K1 C1 D1 K1
拼接拓展:pandas.merge() VS pandas.DataFrame.join() VS numpy.concatenate() VS pandas.concat()
[重点:numpy.concatenate()可以进行上下或者左右拼接,由axis参数确定;而pandas.merge 和 pandas.join 只能进行左右拼接!]
[易错点:numpy.concatenate(), 而不是pandas.concatenate(),所以numpy.concatenate() 能代入 np.ndarray型数据,也能带入DataFrame型数据!]
[易错点:要求numpy.concatenate()里的两个np.ndarray 一定在拼接维度上,维度相等!否则,报错。]
首先我们生成np1,np2 代码如下,
np1 = np.array([[1,2,3],[4,5,6]])
np2 = np.array([[11,22,33,44],[55,66,77,88],[99,00,111,222]])
print(np1)
print(np2)
输出结果如下,
[[1 2 3]
[4 5 6]]
[[ 11 22 33 44]
[ 55 66 77 88]
[ 99 0 111 222]]
然后我们把np1和np2上下拼接,同时拼接方向为np1的纵向,代码如下
np3 = np.concatenate((np1, np2.T),axis= 0)
print(np3)
最后得出结果,如下
[[ 1 2 3]
[ 4 5 6]
[ 11 55 99]
[ 22 66 0]
[ 33 77 111]
[ 44 88 222]]
pandas.concat() 等价于 numpy.concatenate() 方法
三、pandas.DataFrame的常用统计方法
pandas.DataFrame有4个常用内置统计方法,都是以列做运算
求列和:pandas.DataFrame.sum()
求列均值:pandas.DataFrame.mean()
求列累加和:pandas.DataFrame.cumsum()
求列统计量(包括列元素个数,列均值,列标准差,列最小值,列的百分位数和列最大值):pandas.DataFrame.describe()
我们继续用已经获得的数据进行展示一下,
代码如下,
a = np.random.standard_normal((9,4))
a = a.round(6)
df6 = pd.DataFrame(a)
print(df6.sum())
print(df6.mean())
print(df6.cumsum())
print(df6.describe())
结果如下,
2016-12-31 2017-12-31 2018-12-31 2019-12-31
0 -1.101220 -1.349005 0.606338 -1.322234
1 -1.129266 0.632621 -1.460356 0.296983
2 -0.791004 0.312555 0.694449 0.266228
3 -0.541898 0.061317 -1.061466 -0.680826
4 -0.539163 0.351453 1.636628 -0.664157
5 0.803651 0.748810 0.087098 0.386566
6 -1.656814 0.882635 0.797272 -0.959593
7 0.632578 -1.498644 1.546371 -0.404477
8 1.180458 0.882217 0.190661 0.354593
2016-12-31 -3.142678
2017-12-31 1.023959
2018-12-31 3.036995
2019-12-31 -2.726917
Freq: A-DEC, dtype: float64
2016-12-31 -0.349186
2017-12-31 0.113773
2018-12-31 0.337444
2019-12-31 -0.302991
Freq: A-DEC, dtype: float64
2016-12-31 2017-12-31 2018-12-31 2019-12-31
0 -1.101220 -1.349005 0.606338 -1.322234
1 -2.230486 -0.716384 -0.854018 -1.025251
2 -3.021490 -0.403829 -0.159569 -0.759023
3 -3.563388 -0.342512 -1.221035 -1.439849
4 -4.102551 0.008941 0.415593 -2.104006
5 -3.298900 0.757751 0.502691 -1.717440
6 -4.955714 1.640386 1.299963 -2.677033
7 -4.323136 0.141742 2.846334 -3.081510
8 -3.142678 1.023959 3.036995 -2.726917
2016-12-31 2017-12-31 2018-12-31 2019-12-31
count 9.000000 9.000000 9.000000 9.000000
mean -0.349186 0.113773 0.337444 -0.302991
std 0.986478 0.914638 1.050823 0.646661
min -1.656814 -1.498644 -1.460356 -1.322234
25% -1.101220 0.061317 0.087098 -0.680826
50% -0.541898 0.351453 0.606338 -0.404477
75% 0.632578 0.748810 0.797272 0.296983
max 1.180458 0.882635 1.636628 0.386566
总结
以上就是今天的经验分享,从拓展已有pandas.DataFrame到两个常用方法,join和groupby,最后又介绍了一下panadas常用的统计方法。相信这些经验都能帮助你日后在数据分析中大展身手~ 如果觉得今天的分析对你有帮助,请点个赞鼓励一下吧~~