【CSDN软件工程师能力认证学习精选】 python科学计算——pandas

CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。

我们每天将都会精选CSDN站内技术文章供大家学习,帮助大家系统化学习IT技术。

写在前面

pandas在数据处理分析上往往占据主要地位,其中实现了很多功能函数,可以使数据分析更加方便快捷,这里只是pandas中比较基础的总结,更加复杂高级的用法还需要参考官方文档。pandas中两个常用的对象是Series和DataFrame。

Series对象

series是pandas中最基本的对象,并定义了和numpy.ndarray的接口,可以用numpy的函数直接操作series对象。series由两部分组成:index和values,index可看作一个索引,在创建series时可以指定index,若不指定,则会创建一个默认的index,values是保存元素值得narray数组。

s = pd.Series([1,2,3,4,5], index=["a","b","c","d","e"])
print s.index
print s.values
##
Index([u'a', u'b', u'c', u'd', u'e'], dtype='object')
[1 2 3 4 5]

series支持两种索引,一是如numpy.narray的索引类型,第二是这里的index索引。

print s[1]
print s["a"]
#
2
1

另外series也支持两种切片类型,两者的区别是使用数字索引时和numpy.narray的一样,但使用这里的index切片时,会包括起点和终点值。

print s[1:3]
print s["b":"d"]
##
b    2
c    3
dtype: int64
b    2
c    3
d    4
dtype: int64

series对象之间可以进行运算,在进行运算时会将元素对齐,如果长度不一样时,多余的部分结果时NaN,该值时浮点数中一个特殊值。

s2 = pd.Series([1,2,3,4,5,6], index=["a","b","c","d","e","f"])
s+s2
#
a     2.0
b     4.0
c     6.0
d     8.0
e    10.0
f     NaN
dtype: float64

DataFrame对象

DataFrame是pandas中最常用的数据类型,同时提供了许多将其它数据结构转化为DataFrame的函数,并且提供了从许多不同类型文件直接读取数据并以DataFrame对象返回。DataFrame对象的基本结构如下图: 
这里写图片描述
DataFrame的同一列必须是同一类型数据,不同列可以是不同类型数据。通过[]+列索引来获取某一列,这是获取的类型是Series类型,当[]+列索引列表时将得到一个DataFrame类型。使用.loc[]将获得数据的某一行,返回的是Series类型,由于各列类型不一样,在获取时将会转换成通用的object类型,同样,为一个列表时将会时一个DataFrame类型。values属性将会把DataFrame转换成一个数组,由于数据类型不一样,所以最终仍时一个object类型的数组。

DataFrame的构造

DataFrame可以通过三个参数来构造,data是数据,index行索引,columns列索引。data可以是二维数组、字典,当为字典是,key是行索引,value可以是一维数组、列表或者Series对象。

df1 = pd.DataFrame(np.random.randint(0,10,(4,2)),index=["a","b","c","d"], columns=["A","B"])
df2 = pd.DataFrame({"a":[1,2,3,4],"b":[5,6,7,8],index=["A","B","C","D"]})
arr = np.array([("i1",1),("i2",2),("i3",3),("i4",4)],dtype=[("name","10s"),("count",int)])
df3 = pd.DataFrame(arr)

此外还可以调用以 from_开头的类方法,将特定格式的数椐转换成 DataFrame对象。from_dict()将字典转换为DataFrame对象,其 orient参数可以指定字典键对应的方向,默认值为”columns”,表示把字典的键转换为列索引,即字典中的每个值与一列对应。而 orient参数为”index”时,字典中的每个值与一行对应。当字典为嵌套字典,即字典的值为字典时,另外一个轴的索引值由第二层字典屮的键决定。

dictl = {"a":[1, 2, 3], "b":[4, 5, 6]}
dict2 = {"a":{"A":1,"B":2}, "b":{"A":3, "C":4}}
dfl = pd.DataFrame.from_dict(dictl, orient="index")
df2 = pd.DataFrame.from_dict(dictl, orient="columns")
df3 = pd.DataFrame.from_dict(dict2, orient="index")
df4 = pd.DataFrame.from_dict(dict2, orient="columns")
###############################################################

from_items()将key-value序列转换为DataFrame对象,其中value是一维数据的列表、数组或Series对象,当orient指定为index时,需要指定columns索引。若不指定将产生错误。

df1 = pd.DataFrame.from_items(items,orient="index",columns=["A","B","C"])
  A  B  C
a  1  2  3
b  4  5  6
#######################################
df2 = pd.DataFrame.from_items(items,orient="columns")
   a  b
0  1  4
1  2  5
2  3  6

将DataFrame转换为其它格式数据

to_dict将DataFrame对象转化为字典,其orient参数决定字典的元素的类型:

# records指定字典类型
df2.to_dict(orient="records")
[{'a': 1, 'b': 4}, {'a': 2, 'b': 5}, {'a': 3, 'b': 6}]
# list指定列表类型
df2.to_dict(orient="list")
{'a': [1L, 2L, 3L], 'b': [4L, 5L, 6L]}
# dict指定嵌套字典类型
df2.to_dict(orient="dict")
{'a': {0: 1L, 1: 2L, 2: 3L}, 'b': {0: 4L, 1: 5L, 2: 6L}}

to_records()将DataFrame对象转化成结构数组,若index参数为True(默认),则返回的数据包含行索引数据。

df2.to_records()
rec.array([(0, 1, 4), (1, 2, 5), (2, 3, 6)], 
          dtype=[(u'index', '<i8'), (u'a', '<i8'), (u'b', '<i8')])
df2.to_records(index=False)
rec.array([(1, 4), (2, 5), (3, 6)], 
          dtype=[(u'a', '<i8'), (u'b', '<i8')])

Index对象

Index对象保存的是索引标签数据,它可以快速的找到标签对应的整数下标,可看成字典类型,通过Index.values属性可获得保存索引的数组,其元素类型是object,Index是只读类型,一旦创建就无法修改其元素。

df2.columns
Index([u'a', u'b'], dtype='object')
df2.columns.values
array(['a', 'b'], dtype=object)

Index对象可以通过get_loc()和get_indexer()来获取索引相应的整数下标,前者是获取一个,后者是获取一组,当Index中不存在该索引时,则返回-1。

df2.columns.get_loc("a")
0
df2.columns.get_indexer(["a","b","c"])
array([ 0,  1, -1])

MultiIndex对象

MultiIndex继承于Index,是多级索引的对象,通过[]获取单个元素,返回的结果依然是一个多级标签,同样可以用get_loc()和get_indexer()来获取单个和多个标签的下标。我们再次拿上面那副图作为例子: 
这里写图片描述
假设这幅图的DataFrame对象为df,则可以验证下面的:

mindex = df.index
mindex[1]
('0-10','Slope')
mindex.get_loc(('0-10','Slope'))
1
mindex.get_indexer([('10-30','Top'),('0-10','Depression'),'nothing'])
[5 0 -1]

获取每一级的索引可以用level属性,level返回的是一个多维数组,level[0]是顶级所以,level[1]是下一级索引。

mindex.level[0]
Index([u'0-10',u'10-30'], dtype='object', name=u'depth')
mindex.level[1]
Index([u'Depression',u'Slope',u'Top'],dtype='object',name=u'Contour')

当把一个元组列表传递给Index对象时,将自动创建MutliIndex对象,若希望创建的是元组Index对象,则设置tupleize_cols为False。

pd.Index([("A", "x"), ("A", "y"), ("B", "x"), ("B", "y")], name=["classl", "class2"])
MultiIndex(levels=[[u'A', u'B'], [u'x', u'y']],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=[u'classl', u'class2'])

此外可以使用以from_开头的Multiindex类方法从特定的数据结构创建Multiindex对象。例如 from_airays()方法从多个数组创建Multiindex对象:

classl = ["A", "A", "B", "B"]
class2 = ["x", "y", "x", "y"]
pd.MultiIndex.from_arrays([classl, class2], names=["classl", "class2"])
MultiIndex(levels=[[u'A', u'B'], [u'x', u'y']],
           labels=[[0, 0, 1, 1], [0, 1, 0, 1]],
           names=[u'classl', u'class2'])

from_product()则从多个集合的笛卡尔积创建 Multiindex对象。下而的程序将所创建的Multiindex对象传递给index和 columns参数,所创建的DataFrame对象的行和列使用同一个多级索引对象。

下标存取

[]操作符

[]支持如下几种下标对象:

  1. 单个索引标签,获取标签对应的列,返回一个Series对象;
  2. 多个索引标签,获取各个标签对应的列,返回一个DataFrame对象;
  3. 整数切片,返回整数下标对应的行;
  4. 标签切片,返回包含终值;
  5. 布尔数组,返回bool数组中为True对应的行;
  6. 布尔DataFrame,把DataFrame中为Fasle的元素设置为NaN。
np.random.seed(42)
df = pd.DataFrame(np.random.randint(0,10,(5,3)), index=["r1","r2","r3","r4","r5"], columns=["c1","c2","c3"])
    c1  c2  c3
r1  6   3   7
r2  4   6   9
r3  2   6   7
r4  4   3   7
r5  7   2   5
df[2:4]                             df["r2":"r4"]
    c1  c2  c3                        c1    c2  c3
r2  4   6   9                       r3 2    6   7
r3  2   6   7                       r4 4    3   7
r4  4   3   7

df > 2                                     df[df>2]
    c1  c2  c3                              c1  c2  c3
r1  True    True    True               r1   6.0 3.0 7
r2  True    True    True               r2   4.0 6.0 9
r3  False   True    True               r3   NaN 6.0 7
r4  True    True    True               r4   4.0 3.0 7
r5  True    False   True               r5   7.0 NaN 5

.loc[]和.iloc[]存取器

.loc[]的下标对象是一个元组,其中的两个元素分别与DataFrame的两个轴相对应。若下标不是元组,则该下标对应第0 轴,对应第1轴。每个轴的下标对象都支持单个标签、标签列表、标签切片以及布尔数组。

df.loc[["r2","r3"]]             df.loc[["r2","r3"],["c1","c2"]]
    c1  c2  c3                      c1  c2
r2  4   6   9                   r2  4   6
r3  2   6   7                   r3  2   6

iloc[]和loc[]相似,只不过iloc是用整数下标存取。ix[]可以把标签和整数混用:

df.ix[2:4,["c1","c3"]]
    c1  c3
r3  2   7
r4  4   7

.at[]和.iat[]存取单个元素

.at[]分别传入行列的标签,获取该行列的元素,.iat[]传入的是整数下标,此外,get_value()与.at[]类似,但效率要比.at[]快。

过滤筛选

在对DataFrame进行条件过滤时,可以使用bool数组进行过滤,除此,query()方法可以实现相同的功能,query()接受一个字符串条件:

df.query("c1>2 & c1<7")
    c1  c2  c3
r1  6   3   7
r2  4   6   9
r4  4   3   7

有时候,需要用到全局或局部的变量进行过滤,则在变量名前加@:

low = 2
hi = 7
df.query("c1>@low & c1<@hi")
    c1  c2  c3
r1  6   3   7
r2  4   6   9
r4  4   3   7

文件读写

pandas提供了很多与文件读写的函数,方便从文件中读取内容,返回DataFrame对象,同时能将DataFrame对象存储在文件中。pandas能方便与下面格式的文件交互: 
这里写图片描述
这些函数的参数很多,所以这里不进行详细总结,可以参看官方文档。

数值运算

Series和DataFrame对象都支持Numpy的接口,因此可以使用Numpy提供的ufunc函数,而且也提供了各种运算方法,比如mean()、std()、max()等,这些函数和numpy中类似,都有三个常用参数:axis指定运算轴;level指定运算对应的索引级别;skipna是否跳过NaN。此外Pandas还提供了 add()、 sub()、 mul()、 div()、 mod()等二元运算符对应的函数。这些函数可以通过axis、 level和 fill_value等参数控制其运算行为。

字符串处理

pandas提供了大量的字符串处理函数,正由于函数数量过大,所以pandas提供了str(类似命名空间)来包装这些函数,例如将字符转换成大写:

se = pd.Series(["a","b","c"])
se.str.upper()
0    A
1    B
2    C
dtype: object

Python中包含两种字符串:字节字符串和Unicode字符串。通 过 str.decode()可以将字节字符串按照指定的编码解码为Unicode字符串。例如在UTF-8编码屮,一个汉字占用三个字符,因此下面的s_utf8 中的字符串长度分别为6、9、12。当调用str.decode()将其转换为Unicode字符串的序列之后,其各个元素的长度为实际的文字个数。 str.encode()可以把Unicode字符串按照指定的编码转换为字节字符串,在常用的汉字编码GB2312中,一个汉字占州两个字节,因此s_gb2312的元素长度分别为4、 6、 8。

s_utf8 = pd.Series([b"成都",b"成都市",b"四川成都"])
s_unicode = s_utf8.str.decode("utf-8")
s_gb2312 = s_unicode.str.encode("gb2312")
print s_utf8.str.len()
print s_unicode.str.len()
print s_gb2312.str.len()
0     6
1     9
2    12
dtype: int64
0    2
1    3
2    4
dtype: int64
0    4
1    6
2    8
dtype: int64

可以对str使用切片或下标,相当于对Series的每个元素都使用下标或切片:

s_unicode.str[:2]
0    成都
1    成都
2    四川
dtype: object

字符串序列和字符串一样,支持加法和乘法运算:

s_abc = pd.Series([u'a',u'b',u'c'])
s_unicode+u'-'+s_abc*2
0      成都-aa
1     成都市-bb
2    四川成都-cc
dtype: object

cat()函数能够连接两个字符串序列对象:

s_unicode.str.cat(s_abc,sep='_')
0      成都_a
1     成都市_b
2    四川成都_c
dtype: object

split()能够对字符串序列的每个元素进行分割,而join()函数能将一个字符串序列对象的元素连接起来:

s = pd.Series(['a|bc|de','x|xyz|yz'])
s_list = s.str.split("|")
0     [a, bc, de]
1    [x, xyz, yz]
dtype: object
s_list.str.join('*')
0     a*bc*de
1    x*xyz*yz
dtype: object

对于这种字符串序列对象,[]将会对每个字符序列的列表元素进行相应的操作:

s_list.str[1]
0     bc
1    xyz
dtype: object

还可以转换为嵌套列表,然后转换为DataFrame对象:

pd.DataFrame(s_list.tolist(), columns=["A","B","C"])
    A   B   C
0   a   bc  de
1   x   xyz yz

在字符串处理时,正则表达式时一个强有力的工具,而pandas也提供了如此的方法str.extract(),返回的时DataFrame对象,该对象若不指定组时,得到的DataFrame对象将会自动进行标签名设置,若指定,则返回的时带标签的DataFrame对象。

s.str.extract(r"(\w+)\|(\w+)\|(\w+)")
    0   1   2
0   a   bc  de
1   x   xyz yz
s.str.extract(r"(?P<A>\w+)\|(?P<B>\w+)|")
    A   B
0   a   bc
1   x   xyz

时间序列

pandas提供了时间点、时间段、时间间隔三种时间类型,封装在Timestamp对象内,该对象继承与python内置的datetime类,表示时间轴上的一个时间点,通过Timestamp.now()可以获取当前时间,该时间是不带时区信息的,通过tz_localize()将时间转化为带时区的时间对象,带时区时间对象可以通过tz_convert()转换为其它时区时间。

now = pd.Timestamp.now()
now_shanghai = now.tz_localize("Asia/Shanghai")
now_tokyo = now_shanghai.tz_convert("Asia/Tokyo")
print now
print now_shanghai
print now_tokyo
2017-12-18 10:59:30.939000
2017-12-18 10:59:30.939000+08:00
2017-12-18 11:59:30.939000+09:00

带时区时间的不同对象可以比较,但不带时区时间和带时区时间对象是无法比较的。所有的时区名在pytz模块的common_timezones()中规定。

now_shanghai == now_tokyo
True

Period对象表示一个标准的时间段,例如某年、某月等,时间段的长短由freq参数决定。

now_day = pd.Period.now(freq="D")
now_time = pd.Period.now(freq="H")
print now_day
print now_time
2017-12-18
2017-12-18 11:00

freq属性是一个描述时间段的字符串,其可选值可以通过下面的代码获得: 
from pandas.tseries import frequencies 
frequencies._period_code_map.keys() 
frequencies._period_alias_dictionary() 
对于周期为年度和星期的时间段,可以通过freq指定开始的时间。例如”W”表示以星期天开始的星期时间段,而”W-MON”则表示以星期一开始的星期时间段:

now_week_sun = pd.Period.now(freq="W")
now_week_mon = pd.Period.now(freq="W-MON")
print now_week_sun
print now_week_mon
2017-12-18/2017-12-24
2017-12-12/2017-12-18

时间段的起点和终点可以通过start_time和end_time获取,这两个属性都是Timestamp对象。to_period()函数可以将时间点对象转换为包含该时间点的时间段,该时间段不包含时区信息。

now_shanghai.to_period("H")
Period('2017-12-18 10:00', 'H')

Timestamp和Period对象可以其属性获取年月日。将两个时间点相减便得到表示时间间隔的Timedelta对象。

fest_day = pd.Timestamp("2018-1-1")
fest_day - now
Timedelta('13 days 13:00:29.061000')

时间间隔依然由相关属性来获取间隔的天数、分秒等。

NaN相关的函数

NaN是一个浮点数的特殊值,无法在整数中使用,所以,当整数数列中出现NaN,那么整数将转化为浮点数。DataFrame的where函数会将False对象的元素设置为NaN。

df = pd.DataFrame(np.random.randint(0,10,(3,3)), columns=list("ABC"))
   A  B  C
0  1  8  4
1  1  3  6
2  5  3  9
df_nan = df.where(df>2)
     A  B  C
0  NaN  8  4
1  NaN  3  6
2  5.0  3  9

isnull()和notnull()函数判断元素是否为NaN,两者的结果都是bool类型的DataFrame,两者的bool类型相反,但是实质是一样的。但notnull()会少创建一个临时对象,相对效率较高。

df_nan.isnull()
     A         B     C
0   True    False   False
1   True    False   False
2   False   False   False
df_nan.notnull()
      A       B      C
0   False   True    True
1   False   True    True
2   True    True    True

count()返回每列或每行的非NaN的元素个数,默认为列,即axis=0:

df_nan.count()
A    1
B    3
C    3
dtype: int64
df_nan.count(axis=1)
0    2
1    2
2    3
dtype: int64

在实际应用时最干脆的方法是对NaN的行列直接删除,这适合于包含NaN的行列在总数中占的比例很小的时候,通过thresh可以控制对NaN的筛选,只删除大于等于thresh的行。

df_nan.dropna()
    A   B   C
2   5.0 3   9
df_nan.dropna(thresh=1)
    A   B   C
0   NaN 8   4
1   NaN 3   6
2   5.0 3   9

有时候不能直接删除NaN的行列,这时候需要对其填充,ffill()使用之前的数据填充;bfill()使用之后的数据填充;interpolate()使用前后插值填充。interpolate()默认使用等距线性插值,可以通过其method参数指定插值算法。

s = pd.Series([3,np.NaN,7], index=[0,8,9])
s.interpolate()
0    3.0
8    5.0
9    7.0
dtype: float64
s.interpolate(method="index")
0    3.000000
8    6.555556
9    7.000000
dtype: float64

interpolate()默认使用前后两个值得平均值,当method=”index”时,根据index来进行插值,由于8和9比较接近,所以插值后离7比较近。此外,还可以用fillna()函数对不同列进行不同值填充,参数是以字典形式传入。

df_nan.fillna({"A":3.0})
    A   B   C
0   3.0 8   4
1   3.0 3   6
2   5.0 3   9

各种聚合方法的skipna参数默认为True, 因此计兑时将忽略NaN 元素,注意每行或每列是单独运算的。如果需要忽略包含NaN 的整行,需要先调用dropna()。若 将 skipna参数设置为False, 则包含NaN 的行或列的运算结果为NaN。

df_nan.sum()
A     5.0
B    14.0
C    19.0
dtype: float64
df_nan.sum(skipna=False)
A     NaN
B    14.0
C    19.0
dtype: float64
df_nan.dropna().sum()
A    5.0
B    3.0
C    9.0
dtype: float64

df.combine_first(other)使用other填充df中的NaN元素。它 将 df中的NaN元素替换为other中对应标签的元素。

DataFrame增添删除

DataFrame同时提供了对DataFrame对象得增删该查函数,这些函数包括: 
这里写图片描述

增删行列

DataFrame可以看作是Series组成的字典,通过DataFrame[colname]=values可以添加新的列,如果需要从已有的列通过计算来得到新的列,则可以通过eval函数。

df = pd.DataFrame(np.random.randint(0,10,(4,4)), columns=list("ABCD"))
  A  B  C  D
0  6  9  1  9
1  4  2  6  7
2  8  8  9  2
3  0  6  7  8
df["newcol"] = df.eval("A+10")
 A  B  C  D  newcol
0  6  9  1  9  16
1  4  2  6  7  14
2  8  8  9  2  18
3  0  6  7  8  10

assign()方法添加关键字指定的新列,其它内容保持不变。

df.assign(newcol2=df.A+1)
    A   B   C   D   newcol  newcol2
0   6   9   1   9   16      7
1   4   2   6   7   14      5
2   8   8   9   2   18      9
3   0   6   7   8   10      1

append()方法用于添加行,它没有inplace参数,只能返冋一个全新对象。由于每次调用append()都会复制所有的数据,因此在循环屮使用append()添加数据会极大地降低程序的运总速度。可以使用一个列表缓存所有的分块数据,然后调用concat()将所有这些数据沿着指定轴拼贴到一起。

def rand_dataframe(n):
    columns=["A","B","C"]
    for i in range(n):
        nrow = np.random.randint(10,20)
        yield pd.DataFrame(np.random.randint(0,100,size=(nrow,3)), columns=columns)      
df_list = list(rand_dataframe(100))
df_res1 = pd.DataFrame([])
for df in df_list:
    df_res1 = df_res1.append(df)

######################################################
df_res2 = pd.concat(df_list,axis=0)

drop()函数能删除指定标签的行和列.

df = pd.DataFrame(np.random.randint(0,100,size=(10,10)), columns=list("ABCDEFGHIJ"))
df.drop(["A","B"], axis=1)
df.drop([0,1], axis=0)

reset_index()可以将索引转换为列,level指定转换的索引级别,如果只希望从索引中删除某个级别,可以设置drop参数为True。

df.reset_index()

set_index()可以将指定列转换为index,append参数为True时,为当前索引添加新的级别,为False时,将删除原先的index。stack()方法把指定级別的列索引转换为行索引,而unstack()则把行索引转换为列索引。无论是stack()还是unstack(),当所有的索引被转换到同一个轴上时,将得到一个Series对象。reorder_levels()和 swaplevel()交换指走轴的索引级别。

分组运算

所谓分组运算是指使用特定的条件将数裾分为多个分组,然后对每个分组进行运算,最后再将结果整合起来。Pandas中的分组运算由DataFrame或 Series对象的groupby()方法实现。当分组用的数据在源数据中时,可以直接通过列名指定分纟11数据。当源数据是DataFrame类型时,groupby()方法返回一DataFrameGroupBy对象。源数据为Series类型,则返SeriesGroupBy对象。


Dose    Res1    Res2    Tmt Age Gender
0   50  9.90    10.00   C   60  F
1   15  0.02    0.04    D   60  F
2   25  0.63    0.80    C   50  M
df.groupby("Tmt")
<pandas.core.groupby.DataFrameGroupBy object at 0x0959FD70>

还可以使用列表传递多组分组数据给groupby():

df.groupby(["Tmt","Age"])

可以通过len()获取分组数:

print len(tmt)
2

GroupBy对象支持迭代接口,它与字典的iteritems()方法类似,每次迭代得到分组的键和数据。当使用多列数据分组时,与每个组对应的键是一个元组。

for key , df in tmt:
    print "key=", key,",shape=",df.shape
key= C ,shape= (2, 6)
key= D ,shape= (1, 6)

get_group()方法可以获得与指定的分组键对应的数据:

tmt.get_group("C")
    Dose    Res1    Res2    Tmt Age Gender
0   50  9.90    10.0    C   60  F
2   25  0.63    0.8 C   50  M
tmt.get_group("D")
    Dose    Res1    Res2    Tmt Age Gender
1   15  0.02    0.04    D   60  F

对GroupBy的下标操作将获得一个只包含源数据中指定列的新GroupBy象,GroupBy类中定义了getattr() 方法,因此当获取GroupBy中未定义的属性时,将按照下 
面的顺序操作: 
•如果属性名是源数据对象的某列的名称,则相当于GroupBy[name], 获取针对该列的GroupBy对象。 
•如果属性名是源数据对象的方法,则相当于通过apply()对每个分组调用该方法。注意Pandas中定义了转换为apply()的方法集合,只有在此集合之中的方法才会被自动转换。 
通过GroupBy对象提供的agg()、transform()、filter()以及apply()等方法可以实现各种分组运算。每个方法的第一个参数都是一个回调函数,该函数对每个分组的数据进行运算并返回结果。这些方法根据回调函数的返回结果生成最终的分组运算结果。

agg()聚合

agg()对每个分组中的数据进行聚合运算。所谓聚合运算是指将一组由N个数值组成的数据转换为单个数值的运算,例如求和、平均值、中间值甚至随机取值等都是聚合运算。其回调函数接收的数据是表示每个分组中每列数据的Series对象,若回调函数不能处理Series对象,则agg()会接着尝试将整个分组的数据作为DataFmme对象传递给回调函数。回调函数对其参数进行聚合运算,将 Series对象转换为单个数值,或将 DataFrame对象转换为Series对象。agg()返冋一个DataFmme对象,其行索引为每个分组的键,而列索引为源数据的列索引。

transform()转换

transform()对每个分组中的数据进行转换运算。与agg()相同,首先尝试将表示每列的Series对象传递给回调函数,如果失败,将表示整个分组的DataFmme对象传递给回调函数。回调函数的返回结果与参数的形状相同,transform()将这些结果按照源数据的顺序合并在一起。

filter()过滤

filter()对每个分组进行条件判断。它将表示每个分组的DataFrame对象传递给回调函数,该函数返True或False, 以决定是否保留该分组。filter()的返回结果是过滤掉一些行之后的DataFmme对象,其行索引与源数据的行索引的顺序一致。

apply()

apply()是一个强大的函数,能够实现前面说的几个函数的功能,但由于太灵活,用不好的化可能会出现很大的错误,具体可百度参看详解。

 

关于CSDN软件工程师能力认证

      CSDN软件工程师能力认证(以下简称C系列认证)是由中国软件开发者网CSDN制定并推出的一个能力认证标准。C系列认证历经近一年的实际线下调研、考察、迭代、测试,并梳理出软件工程师开发过程中所需的各项技术技能,结合企业招聘需求和人才应聘痛点,基于公开、透明、公正的原则,甑别人才时确保真实业务场景、全部上机实操、所有过程留痕、存档不可篡改。C系列认证的宗旨是让一流的技术人才凭真才实学进大厂拿高薪,同时为企业节约大量招聘与培养成本,使命是提升高校大学生的技术能力,为行业提供人才储备,为国家数字化战略贡献力量。

 

了解详情可点击:CSDN软件工程师能力认证介绍

 

本文出处:https://blog.csdn.net/unixtch/article/details/78821320?ops_request_misc=&request_id=&biz_id=102&utm_term=python科学计算&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-2-78821320.pc_search_result_before_js&spm=1018.2226.3001.4187

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值