python科学计算——pandas

来源:互联网 发布:折扣软件哪个好 编辑:程序博客网 时间:2024/05/22 06:17

写在前面

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.indexprint 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"]#21

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

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

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

s2 = pd.Series([1,2,3,4,5,6], index=["a","b","c","d","e","f"])s+s2#a     2.0b     4.0c     6.0d     8.0e    10.0f     NaNdtype: 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  Ca  1  2  3b  4  5  6#######################################df2 = pd.DataFrame.from_items(items,orient="columns")   a  b0  1  41  2  52  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.columnsIndex([u'a', u'b'], dtype='object')df2.columns.valuesarray(['a', 'b'], dtype=object)

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

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

MultiIndex对象

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

mindex = df.indexmindex[1]('0-10''Slope')mindex.get_loc(('0-10','Slope'))1mindex.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  c3r1  6   3   7r2  4   6   9r3  2   6   7r4  4   3   7r5  7   2   5
df[2:4]                             df["r2":"r4"]    c1  c2  c3                        c1    c2  c3r2  4   6   9                       r3 2    6   7r3  2   6   7                       r4 4    3   7r4  4   3   7df > 2                                     df[df>2]    c1  c2  c3                              c1  c2  c3r1  True    True    True               r1   6.0 3.0 7r2  True    True    True               r2   4.0 6.0 9r3  False   True    True               r3   NaN 6.0 7r4  True    True    True               r4   4.0 3.0 7r5  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  c2r2  4   6   9                   r2  4   6r3  2   6   7                   r3  2   6

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

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

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

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

过滤筛选

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

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

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

low = 2hi = 7df.query("c1>@low & c1<@hi")    c1  c2  c3r1  6   3   7r2  4   6   9r4  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    A1    B2    Cdtype: 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     61     92    12dtype: int640    21    32    4dtype: int640    41    62    8dtype: 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*20      成都-aa1     成都市-bb2    四川成都-ccdtype: object

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

s_unicode.str.cat(s_abc,sep='_')0      成都_a1     成都市_b2    四川成都_cdtype: 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: objects_list.str.join('*')0     a*bc*de1    x*xyz*yzdtype: object

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

s_list.str[1]0     bc1    xyzdtype: object

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

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

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

s.str.extract(r"(\w+)\|(\w+)\|(\w+)")    0   1   20   a   bc  de1   x   xyz yzs.str.extract(r"(?P<A>\w+)\|(?P<B>\w+)|")    A   B0   a   bc1   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 nowprint now_shanghaiprint now_tokyo2017-12-18 10:59:30.9390002017-12-18 10:59:30.939000+08:002017-12-18 11:59:30.939000+09:00

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

now_shanghai == now_tokyoTrue

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

now_day = pd.Period.now(freq="D")now_time = pd.Period.now(freq="H")print now_dayprint now_time2017-12-182017-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_sunprint now_week_mon2017-12-18/2017-12-242017-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 - nowTimedelta('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  C0  1  8  41  1  3  62  5  3  9df_nan = df.where(df>2)     A  B  C0  NaN  8  41  NaN  3  62  5.0  3  9

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

df_nan.isnull()     A         B     C0   True    False   False1   True    False   False2   False   False   Falsedf_nan.notnull()      A       B      C0   False   True    True1   False   True    True2   True    True    True

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

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

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

df_nan.dropna()    A   B   C2   5.0 3   9df_nan.dropna(thresh=1)    A   B   C0   NaN 8   41   NaN 3   62   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.08    5.09    7.0dtype: float64s.interpolate(method="index")0    3.0000008    6.5555569    7.000000dtype: float64

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

df_nan.fillna({"A":3.0})    A   B   C0   3.0 8   41   3.0 3   62   5.0 3   9

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

df_nan.sum()A     5.0B    14.0C    19.0dtype: float64df_nan.sum(skipna=False)A     NaNB    14.0C    19.0dtype: float64df_nan.dropna().sum()A    5.0B    3.0C    9.0dtype: 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  D0  6  9  1  91  4  2  6  72  8  8  9  23  0  6  7  8df["newcol"] = df.eval("A+10") A  B  C  D  newcol0  6  9  1  9  161  4  2  6  7  142  8  8  9  2  183  0  6  7  8  10

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

df.assign(newcol2=df.A+1)    A   B   C   D   newcol  newcol20   6   9   1   9   16      71   4   2   6   7   14      52   8   8   9   2   18      93   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 Gender0   50  9.90    10.00   C   60  F1   15  0.02    0.04    D   60  F2   25  0.63    0.80    C   50  Mdf.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.shapekey= C ,shape= (2, 6)key= D ,shape= (1, 6)

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

tmt.get_group("C")    Dose    Res1    Res2    Tmt Age Gender0   50  9.90    10.0    C   60  F2   25  0.63    0.8 C   50  Mtmt.get_group("D")    Dose    Res1    Res2    Tmt Age Gender1   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()是一个强大的函数,能够实现前面说的几个函数的功能,但由于太灵活,用不好的化可能会出现很大的错误,具体可百度参看详解。

原创粉丝点击