pandas逐行操作、分箱技术、窗口函数

cummax,cummin,cumprod,cumsum

有时候我们需要求出从第一行开始截止到当前行的最大值、最小值,以及实现累乘、累和等等。

import pandas as pd

df = pd.DataFrame({"a": [10, 20, 15, 50, 40]})

# cummax:求出从第一行开始截止到当前行的最大值
# 第1行为10,第2行为20,第3行为15但是比20小所以还是20,第4行为50,同理第5行也是50
print(df["a"].cummax())
"""
0    10
1    20
2    20
3    50
4    50
Name: a, dtype: int64
"""

# 这个不需要解释了
print(df["a"].cummin())
"""
0    10
1    10
2    10
3    10
4    10
Name: a, dtype: int64
"""

# 对每一行实现累乘
print(df["a"].cumprod())
"""
0         10
1        200
2       3000
3     150000
4    6000000
Name: a, dtype: int64
"""

# 对每一行实现累加
print(df["a"].cumsum())
"""
0     10
1     30
2     45
3     95
4    135
Name: a, dtype: int64
"""

shift:垂直方向移动

import pandas as pd

df = pd.DataFrame({"a": range(1, 10)})
print(df)
"""
   a
0  1
1  2
2  3
3  4
4  5
5  6
6  7
7  8
8  9
"""

df["b"] = df["a"].shift(1)
df["c"] = df["a"].shift(-1)
print(df)
"""
   a    b    c
0  1  NaN  2.0
1  2  1.0  3.0
2  3  2.0  4.0
3  4  3.0  5.0
4  5  4.0  6.0
5  6  5.0  7.0
6  7  6.0  8.0
7  8  7.0  9.0
8  9  8.0  NaN
"""

我们看到,我们某一列使用shift(n),可以使其达到向上或者向下的平移效果。n大于0,表示向上平移n个单位,n小于0表示向下平移n个单位。既然平移了,那么势必就会出现NaN。

想象一个框,shift(1)表示框向上平移一个长度,那么框住的部分就是新的列。

如果我们有这样一个需求,计算某一列的当前元素和上一个元素的差,该怎么做呢?

import pandas as pd

df = pd.DataFrame({"a": [10, 20, 15, 50, 40]})

print(df["a"] - df["a"].shift(1))
"""
0     NaN
1    10.0
2    -5.0
3    35.0
4   -10.0
Name: a, dtype: float64
"""

diff:垂直方向相减

这个功能我们已经实现了,可以使用shift平移之后手动相减。但是有一个更简便的方法,也就是diff(n),n大于0,表示当前行与前第n行相减,n小于0,表示当前行与后第n行相减。

import pandas as pd

df = pd.DataFrame({"a": [10, 20, 15, 50, 40]})

df["b"] = df["a"].diff(1)
df["c"] = df["a"].diff(-1)
print(df)
"""
    a     b     c
0  10   NaN -10.0
1  20  10.0   5.0
2  15  -5.0 -35.0
3  50  35.0  10.0
4  40 -10.0   NaN
"""

pct_change:垂直方向相减求比例

和diff(n)比较类似,但是在diff(n)基础之上又做了一层操作。就是减完了之后,用差再除以原来减去的值。

import pandas as pd

df = pd.DataFrame({"a": [10, 20, 15, 50, 40]})

df["b"] = df["a"].diff(1)
df["b_pct"] = df["a"].pct_change(1)
df["c"] = df["a"].diff(-1)
df["c_pct"] = df["a"].pct_change(-1)
print(df)
"""
    a     b     b_pct     c     c_pct
0  10   NaN       NaN -10.0 -0.500000
1  20  10.0  1.000000   5.0  0.333333
2  15  -5.0 -0.250000 -35.0 -0.700000
3  50  35.0  2.333333  10.0  0.250000
4  40 -10.0 -0.200000   NaN       NaN
"""

cut:分箱技术

有时候,我们需要对数据进行分类。比如考生成绩,凡是小于60的归类为不及格,大于等于60小于80的为不错,大于等于80小于等于100为优秀

import pandas as pd

df = pd.DataFrame({"a": [60, 50, 80, 96, 75]})

# bins:为一个数组,从小到大。
df["b"] = pd.cut(df["a"], bins=[0, 59, 79, 100])
# 还可以指定labels,注意:len(labels) == len(bins) - 1,因为bins如果有n个元素,那么会形成n-1个区间
df["c"] = pd.cut(df["a"], bins=[0, 59, 79, 100], labels=["不及格", "不错", "优秀"])
print(df)
"""
    a          b    c
0  60   (59, 79]   不错
1  50    (0, 59]  不及格
2  80  (79, 100]   优秀
3  96  (79, 100]   优秀
4  75   (59, 79]   不错
"""

我们注意到:区间是左开右闭的,如果需要把右边也改成开区间,那么加上right=False即可,默认是为True?

rolling:窗口函数

假设我们有一年的历史数据,我们需要对每8天求一次平均值该怎么做呢?比如:第一行是1~8天的平均值,第二行是2~9天的平均值,第三行是3~10天的平均值。

import pandas as pd

df = pd.DataFrame({"a": [10, 20, 10, 60, 40, 20, 50]})

# 调用rolling(n)方法等于每n行开了一个窗口
# 然后就可以使用window求平均值了
# 这个n必须要大于0,否则报错
window = df["a"].rolling(2)
# 我们说n大于0是往上,为2的话表示每一行往上数,加上本身数两行。所以第一行就是NaN了,因为上面没有了。
print(window.mean())
"""
0     NaN
1    15.0
2    15.0
3    35.0
4    50.0
5    30.0
6    35.0
Name: a, dtype: float64
"""
# 同理n=3,表示往上数3行
# 那么第1行和第2行都会为NaN
print(df["a"].rolling(3).mean())
"""
0          NaN
1          NaN
2    13.333333
3    30.000000
4    36.666667
5    40.000000
6    36.666667
Name: a, dtype: float64
"""

# 当然不光可以求平均值,还可以求最大值,最小值,求和等等
df["b"] = df["a"].rolling(2).max()
df["c"] = df["a"].rolling(2).min()
df["d"] = df["a"].rolling(2).sum()
print(df)
"""
    a     b     c      d
0  10   NaN   NaN    NaN
1  20  20.0  10.0   30.0
2  10  20.0  10.0   30.0
3  60  60.0  10.0   70.0
4  40  60.0  40.0  100.0
5  20  40.0  20.0   60.0
6  50  50.0  20.0   70.0
"""

# 甚至还可以自定义函数
df["e"] = df["a"].rolling(2).sum()
# 每一个窗口可以理解为一个Series,df["a"].rolling(2).sum()等价于df["a"].rolling(2).agg("sum")
# 我们再单独加上一个1
df["f"] = df["a"].rolling(2).agg(lambda x: sum(x) + 1)
print(df[["e", "f"]])
"""
       e      f
0    NaN    NaN
1   30.0   31.0
2   30.0   31.0
3   70.0   71.0
4  100.0  101.0
5   60.0   61.0
6   70.0   71.0
"""

# 如果n=1,那么就是本身了
# 不管调用什么方法,都是它本身, 因为只有窗口大小为1
print((df["a"].rolling(1).sum() == df["a"].rolling(1).min()).all())  # True

原文地址:https://www.cnblogs.com/traditional/p/12234328.html

时间: 2024-11-09 01:39:53

pandas逐行操作、分箱技术、窗口函数的相关文章

基于卡方分箱的评分卡建模

卡方分布-chi-square distribution, χ2-distribution: 若k个独立的随机变量Z1, Z2,..., Zk 满足标准正态分布 N(0,1) , 则这k个随机变量的平方和: 为服从自由度为k的卡方分布,记作:  或者  卡方检验-χ2检验是以χ2分布为基础的一种假设检验方法,主要用于分类变量之间的独立性检验: 基本思想是根据样本数据推断总体分布与期望分布是否有显著性差异,或者推断两个分类变量是否相关或者独立.一般可以设原假设为 :观察频数与期望频数没有差异,或者

数据离散化-分箱

  变量的延申和筛选-连续变量离散化-特征筛选 WOE编码(最优分箱) WOE一般在0.1~3之间波动,IV值做得特征筛选的操作 一般保留>0.03的特征 IV值体现的时X和Y之间的显著性进行筛选 1.逐列分箱并获得IV值 # 运行自定义函数所在文件 对自定义分箱文件要自己理解 %run smob.py # y进行0,1互换 train_data['SeriousDlqin2yrs'] = -(train_data.SeriousDlqin2yrs-1) #因为与自定义函数中的标签0 1设定正好

基本数据类型对象包装类和自动装箱自动拆箱技术

一.基本数据类型对象包装类 byte Byte short Short int  Integer long Long boolean Boolean flaot Float double Double char Character 二.基本数据类型对象包装类的最常见作用 就是用于基本数据类型和字符串类型之间做转换 三.基本数据类型转成字符串:   基本数据类型+"": 基本数据类型.toString(基本数据类型值)   如:Integer.toString(34);将34整数转成字符

MySQL纯透明的分库分表技术还没有

MySQL纯透明的分库分表技术还没有 种树人./oneproxy --proxy-address=:3307 --admin-username=admin --admin-password=D033E22AE348AEB5660FC2140AEC35850C4DA997 --proxy-master-addresses=172.16.132.87:[email protected] --proxy-master-addresses=172.16.3.92:[email protected] --

php中对MYSQL操作之预处理技术(2)数据库dql查询语句

<?php //预处理技术 //创建一个mysqli对象 $mysqli = new MySQLi("主机名","mysql用户名","密码","数据库名"); //判断是否链接成功 if($mysqli->connect_error){ die($mysqli->connect_error); } //创建预编译对象 $sql = "select id,name,age,qq from 表名 wh

超长距离波分传输技术

波分传输是现在的光纤网络最常用的骨干网传输方式,波分传输由CWDM/DWDM波分复用器+EDFA光纤放大器+DCM色散补偿器组成,因此波分传输是一个系统性的.今天我就在这里分享一下超长距离波分传输技术. 一.超长距离传输的类型和应用环境 近年来,波分复用技术主要朝超长距离和大容量传输两个方向发展,鉴于超长距离传输的市场需求和网络趋势,本文将重点集中在长距离传输方面,探讨超长距离传输的解决方案. 超长距离传输包括多跨(放大)段的长距离无电中继传输和单跨(放大)段传输两种.从形态特征角度看,前者通常

php中对MYSQL操作之预处理技术(1)数据库dml操作语句

<?php //预处理技术 //创建一个mysqli对象 $mysqli = new MySQLi("主机名","mysql用户名","密码","数据库名"); //判断是否链接成功 if($mysqli->connect_error){ die($mysqli->connect_error); } //创建预编译对象 $sql = "insert into 表名 (name,qq,age) val

[转]卡方分箱中卡方值的计算

<div class="show-content-free"> <p>关于卡方分箱,网上有很多文章,但几乎没有文章介绍分箱时相邻区间卡方值计算的方法,而本文在介绍卡方分箱的同时,重点介绍了相邻区间卡方值的计算方法.通过本文,希望大家能对卡方分箱有清楚透彻的认识.</p> 分箱是什么 分箱是将连续的变量离散化,将多状态的离散变量合并成少状态.这里要注意的是,不仅仅是连续变量要分箱,状态多的离散变量也需要分箱,之前接触过公司内特征工程的项目,里边就将超过

订单分箱问题

订单分箱需求,我把它简化为如下模型: 一张表实现,实现分箱的效果,总结一下做个小demo. package com.kaspar.order.model; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import