Pandas快速入门(三)—— 运算

1. 统计

1.1 groupby()函数

        使用映射器或一系列列对 DataFrame 进行分组。

        groupby操作涉及分割对象、应用函数以及组合结果的某种组合。这可用于对大量数据进行分组并在这些组上进行计算操作。

DataFrame.groupby(by=None, 
                  axis=_NoDefault.no_default, 
                  level=None, 
                  as_index=True, 
                  sort=True, 
                  group_keys=True, 
                  observed=_NoDefault.no_default, 
                  dropna=True)

参数说明:

参数名说明
by

mapping, function, label, pd.Grouper 或者 list of such。用于确定groupby的组

label示例:df.groupby('category')
list示例:df.groupby(['category'])
mapping:需要按DataFrame的index进行映射,用于对category添加汇总分类。
    这里把水果和蔬菜划分到大组蔬菜水果,米面和粮油划分到大组米面粮油
    示例:df.groupby({0:"水果蔬菜",1:"水果蔬菜",2:"米面粮油",...})
function:自定义函数的入参也是DataFrame的index,输出结果与mapping的例子相同
axis{0 或 'index', 1 或 'columns'}, 默认 0
level
当axis是MultiIndex(层级结构)时,按特定的level进行分组,注意这里的level是int类型,从0开始,0表示第1层,以此类推。不要同时指定by和level。
as_index

bool, 默认 True

返回以组标签作为索引的对象。仅与 DataFrame 输入相关。 as_index=False 实际上是“SQL 风格”的分组输出。此参数对过滤(请参阅用户指南中的过滤)没有影响,例如head()\、tail()和nth()转换。

sort

bool,默认 True

对组键进行排序。关闭此功能可获得更好的性能。请注意,这不会影响每组内的观察顺序。Groupby保留每个组内行的顺序。如果为 False,则组将以与原始 DataFrame 中相同的顺序出现。

group_keys

bool, 默认 True

当调用 apply 并且by参数产生类似索引(即转换)结果时,将组键添加到索引以识别片段。默认情况下,当结果的索引(和列)标签与输入匹配时,不包含组键,否则包含组键。

observed

布尔值,默认 False

这仅适用于任何分类分组。如果为 True:仅显示分类分组的观察值。如果为 False:显示分类分组的所有值。

dropna如果为 True,并且组键包含 NA 值,则 NA 值与行/列一起将被删除。如果为 False,NA 值也将被视为组中的键。

  返回值:DataFrameGroupBy对象。

import pandas as pd
import numpy as np

data = {
    "name":['张一','李二','赵三','李四','王五','张六','王琦'],
    "age":[12,11,13,14,17,13,14],
    "class":[1,1,2,2,1,3,4]
}
index = ['S1','S2','S3','S4','S5','S6','S7']

df = pd.DataFrame(data,index=index)
df1 = df.reindex(index=index,columns=['name','age','class','math'])
df1.iloc[:4,3] = 80
print(df1)
df1 = df1.iloc[:,[1,2,3]]
dfby = df1.groupby(by='class')

for name, group in dfby:
    print(name)
    print(group)
-----------------------------------------------------------------
     name  age  class  math
S1   张一   12      1  80.0
S2   李二   11      1  80.0
S3   赵三   13      2  80.0
S4   李四   14      2  80.0
S5   王五   17      1   NaN
S6   张六   13      3   NaN
S7   王琦   14      4   NaN
1
    age  class  math
S1   12      1  80.0
S2   11      1  80.0
S5   17      1   NaN
2
    age  class  math
S3   13      2  80.0
S4   14      2  80.0
3
    age  class  math
S6   13      3   NaN
4
    age  class  math
S7   14      4   NaN

1.2 mean()函数

        计算组的平均值,排除缺失值。

DataFrameGroupBy.mean(numeric_only = False, engine = None, engine_kwargs = None)

参数说明:

参数名说明
numeric_only布尔值,默认False。仅包含float,int,boolean 列。
engine

str,默认None。

        cython :通过 cython 的 C 扩展运行操作。

        numba:通过 numba 的 JIT 编译代码运行操作。

        None:默认cython 或全局设置 compute.use_numba

engine_kwargs

字典,默认 None

  • 参数engine选cython时,没有可接受的engine_kwargs

  • 参数engine选numba时,引擎可以接受nopython,nogil和parallel字典键。这些值必须是True或False。引擎engine_kwargs的默认值numba是:{{'nopython' : True, 'nogil' : False, 'parallel' : False}} 

返回值:Series或DataFrame

import pandas as pd
import numpy as np

data = {
    "name":['张一','李二','赵三','李四','王五','张六','王琦'],
    "age":[12,11,13,14,17,13,14]
}
index = ['S1','S2','S3','S4','S5','S6','S7']

df = pd.DataFrame(data,index=index)
df1 = df.reindex(index=index,columns=['name','age','math'])
df1.iloc[:4,2] = 80
df2 = df1.iloc[:,[1,2]]
print(df2)
df3 = df2.mean()
print(df3)
------------------------------------------------------------
    age  math
S1   12  80.0
S2   11  80.0
S3   13  80.0
S4   14  80.0
S5   17   NaN
S6   13   NaN
S7   14   NaN
age     13.428571
math    80.000000
dtype: float64

1.3 Apply()函数

        逐组应用函数func,并将结果组合起来。

        传递给的函数必须将数据帧作为其第一个参数并返回数据帧、系列或标量。然后将负责将结果组合回单个数据帧或系列中。因此是一种高度灵活的分组方法。

        apply虽然是一种非常灵活的方法,但其缺点是使用它可能比使用更具体的方法agg、transform慢很多。 Pandas 提供了多种方法,这些方法比用于特定目的的方法要快得多,因此在使用它们之前请尝试使用它们。

DataFrameGroupBy.apply(func, *args, include_groups=True, **kwargs)

        参数说明:

参数名说明
func一个可调用函数,将数据帧作为其第一个参数,并返回数据帧、序列或标量。此外,可调用对象还可以采用位置参数和关键字参数。
include_groups

bool, 默认 True

当为 True 时,如果分组问DataFrame的列,则将尝试将func应用于分组。如果这引发TypeError,则将在排除分组的情况下计算结果。如果为 False,则当应用func时将排除分组。

*args、**kwargs元组和 dict。要传递给func的可选位置参数和关键字参数。

  返回值:Series or DataFrame



import pandas as pd
import numpy as np



data = {
    "name":['张一','李二','赵三','李四','王五','张六','王琦'],
    "age":[12,11,13,14,17,13,14],
    "class":[1,1,2,2,1,3,4]
}
index = ['S1','S2','S3','S4','S5','S6','S7']

df = pd.DataFrame(data,index=index)
df1 = df.reindex(index=index,columns=['name','age','class','math'])
df1.iloc[:6,3] = 80

print(df1)
g = df1.groupby('class')
df2 = g[['age','math']].apply(lambda x:x.sum())
print(df2)
---------------------------------------------------------------------
     name  age  class  math
S1   张一   12      1  80.0
S2   李二   11      1  80.0
S3   赵三   13      2  80.0
S4   李四   14      2  80.0
S5   王五   17      1  80.0
S6   张六   13      3  80.0
S7   王琦   14      4   NaN
        age   math
class             
1      40.0  240.0
2      27.0  160.0
3      13.0   80.0
4      14.0    0.0

1.4 value_counts()函数

        返回一个包含数据框中每个不同行的频率的系列。

DataFrame.value_counts(subset=None, normalize=False, 
                       sort=True, ascending=False, 
                       dropna=True)

参数说明:

参数名说明
subset

label or list of labels

计算唯一组合时使用的列。

normalize

bool,默认 False

返回比例而不是频率。

sort

bool,默认 True

True 时按频率排序。当为 False 时,按 DataFrame 列值排序。

ascending

布尔值,默认 False

按升序排序。

dropna

bool,默认 True

不包括包含 NA 值的行数。

返回值:Series

import pandas as pd
import numpy as np

data = {
    "name":['张一','李二','赵三','李四','王五','张六','王琦'],
    "age":[12,11,13,14,17,13,14],
    "class":[1,1,2,2,1,3,4]
}
index = ['S1','S2','S3','S4','S5','S6','S7']

df = pd.DataFrame(data,index=index)
df1 = df.reindex(index=index,columns=['name','age','class','math'])
df1.iloc[:4,3] = 80
print(df1)
s = df1.value_counts('math',dropna=False)
print(s)
------------------------------------------------------------------
name  age  class  math
S1   张一   12      1  80.0
S2   李二   11      1  80.0
S3   赵三   13      2  80.0
S4   李四   14      2  80.0
S5   王五   17      1   NaN
S6   张六   13      3   NaN
S7   王琦   14      4   NaN
math
80.0    4
NaN     3
Name: count, dtype: int64

2. 合并

2.1 concat()

        concat()沿一个轴连接任意数量的Series/DataFrame对象(即行堆叠),同时对其他轴上的索引执行可选的集合逻辑(并集或交集)。像numpy.concatenate 一样, concat()接受同构类型对象的列表或字典并将它们连接起来。

参数说明:

参数名说明
DataFrame对象列表[df1,df2,df3,...]

返回值:DataFrame

import pandas as pd
import numpy as np

data1 = {
    "name":['张一','李二','赵三','李四','王五','张六','王琦'],
    "age":[12,11,13,14,17,13,14],
    "class":[1,1,2,2,1,3,4]
}
index = ['S1','S2','S3','S4','S5','S6','S7']

df1 = pd.DataFrame(data1)
print(f'第一个数据组:\n{df1}')
data2 = {
    'name':['赵一', '赵二', '赵三', '赵四', '赵五', '赵六', '赵七',],
    'age':np.random.randint(12, high=21, size=7),
    'class':np.random.randint(1, high=4, size=7),
}
df2 = pd.DataFrame(data2)
print(f'第二个数据组:\n{df2}')

df = pd.concat([df1, df2])
print(f'合并后数据组:\n{df}')
-----------------------------------------------------------------
~/Python python concat.py 
第一个数据组:
  name  age  class
0   张一   12      1
1   李二   11      1
2   赵三   13      2
3   李四   14      2
4   王五   17      1
5   张六   13      3
6   王琦   14      4
第二个数据组:
  name  age  class
0   赵一   13      2
1   赵二   13      3
2   赵三   17      2
3   赵四   15      3
4   赵五   16      3
5   赵六   17      3
6   赵七   14      3
合并后数据组:
  name  age  class
0   张一   12      1
1   李二   11      1
2   赵三   13      2
3   李四   14      2
4   王五   17      1
5   张六   13      3
6   王琦   14      4
0   赵一   13      2
1   赵二   13      3
2   赵三   17      2
3   赵四   15      3
4   赵五   16      3
5   赵六   17      3
6   赵七   14      3

2.2 数据库风格连接 join

        join可以使用join()或merge()来执行。默认情况下,join()将连接其索引上的DataFrames。每个方法都有参数,允许您指定要执行的联接类型(LEFT、RIGHT、INNER、FULL)或要联接的列(列名或索引)。

        如果两个键列都包含键为null值的行,则这些行将相互匹配。这与通常的SQL联接行为不同,可能会导致意外的结果。

2.2.1 merge()

pandas.merge(left, right, how='inner', on=None, 
            left_on=None, right_on=None, left_index=False, 
            right_index=False, sort=False, suffixes=('_x', '_y'), 
            copy=None, indicator=False, validate=None)

参数说明:

参数名说明
leftDataFrame or named Series
rightDataFrame or named Series
how{‘left’, ‘right’, ‘outer’, ‘inner’, ‘cross’}, default ‘inner’
on

label or list

要连接的列或索引级别名称。这些必须在两个 DataFrame 中找到。如果on为 None 并且不合并索引,则默认为两个 DataFrame 中列的交集。

left_on

label or list

要连接到左侧 DataFrame 的列或索引级别名称。也可以是左侧 DataFrame 长度的数组或数组列表。这些数组被视为列。

right_on

label or list

要连接到右侧 DataFrame 中的列或索引级别名称。也可以是正确 DataFrame 长度的数组或数组列表。这些数组被视为列。

left_index

bool, 默认 False

使用左侧 DataFrame 的索引作为连接键。如果它是 MultiIndex,则其他 DataFrame 中的键数(索引或列数)必须与级别数匹配。

right_index

bool, 默认 False

使用右侧 DataFrame 的索引作为连接键。如果它是 MultiIndex,则其他 DataFrame 中的键数(索引或列数)必须与级别数匹配。

sort

bool,默认 False

在结果 DataFrame 中按字典顺序对连接键进行排序。如果为 False,则连接键的顺序取决于连接类型(how 关键字)。

suffixes

列表,默认为(“_x”,“_y”)

长度为 2 的序列,其中每个元素都可以是一个字符串,指示分别添加到左侧和右侧重叠列名称的后缀 。传递None值而不是字符串,以指示左侧或 右侧的列名称应保持原样,不带后缀。至少其中一个值不得为 None。

copy

bool,默认 True

如果为 False,请尽可能避免复制

indicator

bool 或 str,默认 False

如果为 True,则向输出 DataFrame 添加一列名为“_merge”的列,其中包含有关每行源的信息。可以通过提供字符串参数来为该列指定不同的名称。该列将具有分类类型,对于合并键仅出现在左侧 DataFrame 中的观察,值为“left_only”;对于合并键仅出现在右侧 DataFrame 中的观察,值为“right_only”;如果观察的合并键为“both”在两个 DataFrame 中都可以找到。

validate

str,可选

如果指定,则检查合并是否属于指定类型。

  • “one_to_one”或“1:1”:检查合并键在左右数据集中是否唯一。

  • “one_to_many”或“1:m”:检查合并键在左侧数据集中是否唯一。

  • “many_to_one”或“m:1”:检查合并键在正确的数据集中是否唯一。

  • “many_to_many”或“m:m”:允许,但不会导致检查。

返回值:两个合并对象的DataFrame

import pandas as pd
import numpy as np

data1 = {
    "id":[1,2,3,4,5,6],
    "age":np.random.randint(15, 20, size=6),
    "class":np.random.randint(1, 4, size=6)
}

df1 = pd.DataFrame(data1)

data2 = {
    "id": [1, 2, 4, 5, 6],
    "name": ["John", "Smith", "Jesse", "Neal", "Bob"],
}

df2 = pd.DataFrame(data2)
df_left = pd.merge(df1, df2, on="id", how="left")
df_right = pd.merge(df1, df2, on="id", how="right")
df_inner = pd.merge(df1, df2, on="id", how="inner")
df_outer = pd.merge(df1, df2, on="id", how="outer")
df_cross = pd.merge(df1, df2, how="cross")
print(f'左连接结果:\n{df_left}')
print(f'右连接结果:\n{df_right}')
print(f'内连接结果:\n{df_inner}')
print(f'外连接结果:\n{df_outer}')
print(f'笛卡尔积结果:\n{df_cross}')
----------------------------------------------------
左连接结果:
   id  age  class   name
0   1   18      2   John
1   2   15      2  Smith
2   3   15      2    NaN
3   4   15      1  Jesse
4   5   18      2   Neal
5   6   19      2    Bob
右连接结果:
   id  age  class   name
0   1   18      2   John
1   2   15      2  Smith
2   4   15      1  Jesse
3   5   18      2   Neal
4   6   19      2    Bob
内连接结果:
   id  age  class   name
0   1   18      2   John
1   2   15      2  Smith
2   4   15      1  Jesse
3   5   18      2   Neal
4   6   19      2    Bob
外连接结果:
   id  age  class   name
0   1   18      2   John
1   2   15      2  Smith
2   3   15      2    NaN
3   4   15      1  Jesse
4   5   18      2   Neal
5   6   19      2    Bob
笛卡尔积结果:
    id_x  age  class  id_y   name
0      1   18      2     1   John
1      1   18      2     2  Smith
2      1   18      2     4  Jesse
3      1   18      2     5   Neal
4      1   18      2     6    Bob
5      2   15      2     1   John
6      2   15      2     2  Smith
7      2   15      2     4  Jesse
8      2   15      2     5   Neal
9      2   15      2     6    Bob
10     3   15      2     1   John
11     3   15      2     2  Smith
12     3   15      2     4  Jesse
13     3   15      2     5   Neal
14     3   15      2     6    Bob
15     4   15      1     1   John
16     4   15      1     2  Smith
17     4   15      1     4  Jesse
18     4   15      1     5   Neal
19     4   15      1     6    Bob
20     5   18      2     1   John
21     5   18      2     2  Smith
22     5   18      2     4  Jesse
23     5   18      2     5   Neal
24     5   18      2     6    Bob
25     6   19      2     1   John
26     6   19      2     2  Smith
27     6   19      2     4  Jesse
28     6   19      2     5   Neal
29     6   19      2     6    Bob

2.2.2 join()

DataFrame.join(other, on=None, how='left', 
               lsuffix='', rsuffix='', sort=False, 
               validate=None)

参数说明:

参数名说明
other

DataFrame、Series 或包含它们任意组合的列表。

索引应该类似于这一列中的一列。如果传递了 Series,则必须设置其 name 属性,该属性将用作生成的连接 DataFrame 中的列名称。

on

str、str 列表或类似数组上,可选

调用者中要连接到other中的索引的列或索引级别名称,否则连接索引上的索引。如果给定多个值,则另一个DataFrame 必须具有 MultiIndex。如果调用 DataFrame 中尚未包含数组,则可以传递数组作为连接键。类似于 Excel VLOOKUP 运算。

how

{'left', 'right', 'outer', 'inner', 'cross'}, 默认'left'

如何处理两个对象的操作。

  • 左:使用调用帧的索引(或列,如果指定了)

  • 右:使用别人的索引。

  • 外部:将调用框架的索引(如果指定了则为列)与其他框架的索引形成并集,并按字典顺序排序。

  • 内部:形成调用帧的索引(或列,如果指定了 on)与其他索引的交集,保留调用帧的顺序。

  • cross:从两个帧创建笛卡尔积,保留左键的顺序。

lsuffix

str,默认 ''

从左框架的重叠列使用的后缀。

rsuffix

str,默认 ''

从右框架的重叠列使用的后缀。

sort

bool,默认 False

通过连接键按字典顺序对结果 DataFrame 进行排序。如果为 False,则连接键的顺序取决于连接类型(how 关键字)。

validate

str,可选

如果指定,则检查连接是否属于指定类型。

  • “one_to_one”或“1:1”:检查连接键在左右数据集中是否唯一。

  • “one_to_many”或“1:m”:检查连接键在左侧数据集中是否唯一。

  • “many_to_one”或“m:1”:检查连接键在正确的数据集中是否唯一。

  • “many_to_many”或“m:m”:允许,但不会导致检查。

返回值:数据框,包含来自调用方和其他方的列的数据框。

import pandas as pd
import numpy as np

data1 = {
    "id":[1,2,3,4,5,6],
    "age":np.random.randint(15, 20, size=6),
    "class":np.random.randint(1, 4, size=6)
}

df1 = pd.DataFrame(data1)

data2 = {

    "name": ["John", "Smith", "Jesse", "Neal", "Bob"],
}

df2 = pd.DataFrame(data2)
df_left = df1.join(df2, how="left", rsuffix="_right", lsuffix="_left")
df_right = df1.join(df2, how="right", rsuffix="_right", lsuffix="_left")
df_inner = df1.join(df2, how="inner", rsuffix="_right", lsuffix="_left")
df_outer = df1.join(df2, how="outer", rsuffix="_right", lsuffix="_left")
df_cross = df1.join(df2, how="cross", rsuffix="_right", lsuffix="_left")
print(f'左连接结果:\n{df_left}')
print(f'右连接结果:\n{df_right}')
print(f'内连接结果:\n{df_inner}')
print(f'外连接结果:\n{df_outer}')
print(f'笛卡尔积结果:\n{df_cross}')
---------------------------------------------------------
左连接结果:
   id  age  class   name
0   1   16      3   John
1   2   19      1  Smith
2   3   16      3  Jesse
3   4   19      1   Neal
4   5   16      3    Bob
5   6   19      1    NaN
右连接结果:
   id  age  class   name
0   1   16      3   John
1   2   19      1  Smith
2   3   16      3  Jesse
3   4   19      1   Neal
4   5   16      3    Bob
内连接结果:
   id  age  class   name
0   1   16      3   John
1   2   19      1  Smith
2   3   16      3  Jesse
3   4   19      1   Neal
4   5   16      3    Bob
外连接结果:
   id  age  class   name
0   1   16      3   John
1   2   19      1  Smith
2   3   16      3  Jesse
3   4   19      1   Neal
4   5   16      3    Bob
5   6   19      1    NaN
笛卡尔积结果:
    id  age  class   name
0    1   16      3   John
1    1   16      3  Smith
2    1   16      3  Jesse
3    1   16      3   Neal
4    1   16      3    Bob
5    2   19      1   John
6    2   19      1  Smith
7    2   19      1  Jesse
8    2   19      1   Neal
9    2   19      1    Bob
10   3   16      3   John
11   3   16      3  Smith
12   3   16      3  Jesse
13   3   16      3   Neal
14   3   16      3    Bob
15   4   19      1   John
16   4   19      1  Smith
17   4   19      1  Jesse
18   4   19      1   Neal
19   4   19      1    Bob
20   5   16      3   John
21   5   16      3  Smith
22   5   16      3  Jesse
23   5   16      3   Neal
24   5   16      3    Bob
25   6   19      1   John
26   6   19      1  Smith
27   6   19      1  Jesse
28   6   19      1   Neal
29   6   19      1    Bob

  • 22
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值