DataFrame高效处理行列数据/倒三角型数据/处理阶梯型数据/根据列的值确定行的值

锲子

在使用pandas处理数据时,遇到了一种要按照留存天数来处理的数据,当列所对应的日期超过了最晚的“今天”那么数据就要置为0,举个例子:
在这里插入图片描述
在这个DataFrame中,需要将超过了今天2022-10-30的数据置为“-”,需要得到下面的一个倒三角形状的数据
在这里插入图片描述
在这个DataFrame中,day_0, day_1, …还可能是week_0, week_1, …,解决这类问题会有很多种方法,比较直观但是复杂度很高的方法就是for 循环遍历行,再遍历列,在遇到大于“今天”的数据时将其值修改为“-”

处理按天为单位的数据

待处理的数据:

import reimport pandas as pddate_unit = "day"
now_date = pd.Timestamp.now().floor("D")
print(now_date)
print(now_date - pd.to_datetime("2022-10-10"))raw_df = pd.DataFrame({"date_str": ["2022-10-27", "2022-10-28", "2022-10-29", "2022-10-30", "2022-10-31"],"day_0": [8, 8, 10, 6, 0],"day_1": [4, 6, 0, 0, 0],"day_2": [6, 7, 0, 0, 0],"day_3": [4, 3, 1, 0, 0],}
)print(raw_df)
# 当前df
#      date_str  day_0  day_1  day_2  day_3
# 0  2022-10-27      8      4      6      4
# 1  2022-10-28      8      6      7      3
# 2  2022-10-29     10      0      0      1
# 3  2022-10-30      6      0      0      0
# 4  2022-10-31      0      0      0      0# 目标df
#     date_str  day_0 day_1 day_2 day_3
# 0 2022-10-27      8     4     6     4
# 1 2022-10-28      8     6     7     3
# 2 2022-10-29     10     0     0     -
# 3 2022-10-30      6     0     -     -
# 4 2022-10-31      0     -     -     -

今日的日期以我处理时的2022-10-31为准,日期的单位是按天,获取今天的日期使用pd.Timestamp.now()比datetime.datetime.now()会更方便转换成其他的格式来使用,

将日期列date_str设置为index并转换为datetime对象方便比较

df.set_index("date_str", inplace=True)
# date_str变成了index放在最左侧
#             day_0  day_1  day_2  day_3
# date_str                              
# 2022-10-27      8      4      6      4
# 2022-10-28      8      6      7      3
# 2022-10-29     10      0      0      1
# 2022-10-30      6      0      0      0
# 2022-10-31      0      0      0      0# 修改index列的类型为datetime类型,之后要用于日期加减运算
df.index = df.index.map(pd.to_datetime)
print(df.index)
# DatetimeIndex(['2022-10-27', '2022-10-27', '2022-10-28', '2022-10-30',
#                '2022-10-31'],
#               dtype='datetime64[ns]', name='date_str', freq=None)

这里用了df.index.map和接下来的df.columns.map,map方法是对DataFrame的整个列的值做运算和各种操作的方法,类似Python内置的map方法,接收一个方法来同时处理多个数据

将列名称的数字提取出来转换为整数,方便日期加减运算,处理完之后要还原列名称,所以拷贝一个副本,完事之后将列名称修改回去

raw_columns = df.columns.copy()
df.columns = df.columns.map(lambda x: int(re.sub("\D", "", x)))  # \d表示匹配数字,大写\D表示匹配非数字,将非数字替换为“”
print(df.columns)  # Int64Index([0, 1, 2], dtype='int64')

使用pandas的整体操作行列的方法df.apply对二维的行和列一起做计算和比较,这里参数axis默认为0使用的是横向操作

df = df.apply(lambda col:# 这里为了方便debug断点调试可以单独写成一个方法就可以在方法里面打断点观察col.where(col.index + pd.Timedelta(col.name, unit=date_unit) <= now_date,"-")
)

其中col.index + pd.Timedelta(col.name, unit=date_unit),col.index就是date_str index中的日期(2022-10-27, 2022-10-28, …),col.name是列的名称现在已经被修改成整数(0, 1, 2…),就是用将df中index的日期加上往后延的留存天数:
在这里插入图片描述
其中col.where(...)的操作是对pd.DataFrame或者pd.DataFrame其中一列pd.Series对象的操作,可以对不满足条件的数据赋予想要的值,第一个参数是一个条件,满足这个条件的数据都会被保留,否则就会被赋予其他的值,这个值就是第二个参数,当然这个值也可以用方法做各种运算


当然也可以纵向操作,不过在这次的情况效率会比横向操作要差,大概率是因为多使用了row.index.map方法

df = df.apply(lambda row:row.where(row.name + row.index.map(lambda x: pd.Timedelta(x, unit=date_unit)) <= now_date,"-"),axis=1
)
df.columns = raw_columns
print(df)

最后把列名称还原,把index转换回列

# 将留存的天数的列还原名称,顺序没有发生改变,直接替换即可
df.columns = raw_columns
# 将index还原为列
df.reset_index(inplace=True)print(df)
#     date_str  day_0 day_1 day_2 day_3
# 0 2022-10-27      8     4     6     4
# 1 2022-10-28      8     6     7     3
# 2 2022-10-29     10     0     0     -
# 3 2022-10-30      6     0     -     -
# 4 2022-10-31      0     -     -     -

完整的代码

import reimport pandas as pddate_unit = "day"
now_date = pd.Timestamp.now().floor("D")
print(now_date)
print(now_date - pd.to_datetime("2022-10-10"))raw_df = pd.DataFrame({"date_str": ["2022-10-27", "2022-10-28", "2022-10-29", "2022-10-30", "2022-10-31"],"day_0": [8, 8, 10, 6, 0],"day_1": [4, 6, 0, 0, 0],"day_2": [6, 7, 0, 0, 0],"day_3": [4, 3, 1, 0, 0],}
)print(raw_df)
# 当前df
#      date_str  day_0  day_1  day_2  day_3
# 0  2022-10-27      8      4      6      4
# 1  2022-10-28      8      6      7      3
# 2  2022-10-29     10      0      0      1
# 3  2022-10-30      6      0      0      0
# 4  2022-10-31      0      0      0      0# 目标df
#     date_str  day_0 day_1 day_2 day_3
# 0 2022-10-27      8     4     6     4
# 1 2022-10-28      8     6     7     3
# 2 2022-10-29     10     0     0     -
# 3 2022-10-30      6     0     -     -
# 4 2022-10-31      0     -     -     -df = raw_df# 将日期列date_str设置为index并转换为datetime对象方便比较
df.set_index("date_str", inplace=True)
#             day_0  day_1  day_2  day_3
# date_str
# 2022-10-27      8      4      6      4
# 2022-10-28      8      6      7      3
# 2022-10-29     10      0      0      1
# 2022-10-30      6      0      0      0
# 2022-10-31      0      0      0      0
df.index = df.index.map(pd.to_datetime)
print(df.index)
# DatetimeIndex(['2022-10-27', '2022-10-27', '2022-10-28', '2022-10-30',
#                '2022-10-31'],
#               dtype='datetime64[ns]', name='date_str', freq=None)# 将列名称的数字提取出来,方便做运算,处理完之后要还原列名称,所以拷贝一个副本,完事之后将列名称修改回去
raw_columns = df.columns.copy()
df.columns = df.columns.map(lambda x: int(re.sub("\D", "", x)))  # \d表示匹配数字,大写\D表示匹配非数字,将非数字替换为“”
print(df.columns)  # Int64Index([0, 1, 2], dtype='int64')
print(df)
df = df.apply(lambda col:col.where(col.index + pd.Timedelta(col.name, unit=date_unit) <= now_date,"-"),# apply还有一个参数axis=0,默认横向操作,也就是一列一列地操作,axis=1时为竖向操作
)# 将留存的天数的列还原名称,顺序没有发生改变,直接替换即可
df.columns = raw_columns
# 将index还原为列
df.reset_index(inplace=True)print(df)
#     date_str  day_0 day_1 day_2 day_3
# 0 2022-10-27      8     4     6     4
# 1 2022-10-28      8     6     7     3
# 2 2022-10-29     10     0     0     -
# 3 2022-10-30      6     0     -     -
# 4 2022-10-31      0     -     -     -

标记位于“今天”的位置提示数据未满

在上面的DataFrame中同时想要标记位于“今天”的数据,以提示这一天的数据是不满一天的,也就是得到一条which_today的这样的数据:

which_todayday_4day_3day_2day_1day_0
df.set_index("date_str", inplace=True)
df.index = df.index.map(pd.to_datetime)which_is_today = df.index.map(lambda x:f"{date_unit}_{(now_date - x).days}"
)
print(which_is_today)
df["which_today"] = which_is_today
print(df)	
# date_str                                       
# 2022-10-27      8     4     6     4       day_4
# 2022-10-28      8     6     7     3       day_3
# 2022-10-29     10     0     0     -       day_2
# 2022-10-30      6     0     -     -       day_1
# 2022-10-31      0     -     -     -       day_0

now_date - x得到一个pd.TimeDelta的时间差对象,可以用.days从这个对象中获取时间差的天数

最后总结一下,这一篇介绍了在同时操作DataFrame行列时使用到的一些方法,主要有Series的map方法,DataFrame的apply方法,DataFrame和Series共有的where方法以及pandas中的一些时间相关操作方法,这些方法在特定业务逻辑的处理中都会有不错的帮助

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469382.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

转载 ---资深HR告诉你:我如何筛选简历与选择人员的

资深HR告诉你&#xff1a;我如何筛选简历与选择人员的 有个公司HR看简历 先直接丢掉一半 理由是不要运气不好的应聘者。 当然这可能只是某些HR面对太多的简历产生了偷懒的情绪&#xff0c;但是不论是Manager&#xff0c;亦或是Team Leader&#xff0c;都会遇到招聘的问题&#…

爬虫实战学习笔记_3 网络请求urllib模块:设置IP代理+处理请求异常+解析URL+解码+编码+组合URL+URL连接

1 设置IP代理 1.1 方法论述 使用urllib模块设置代理IP是比较简单的&#xff0c;首先需要创建ProxyHandler对象&#xff0c;其参数为字典类型的代理IP&#xff0c;键名为协议类型&#xff08;如HTTP或者HTTPS)&#xff0c;值为代理链接。然后利用ProxyHandler对象与buildopene…

vim 插件cscope 使用

&#xff11;&#xff0e;安装 sudo apt-get install cscope &#xff12;&#xff0e;初始化 cscope -Rbq 你想在哪个目录下面用这个功能&#xff0c;就在哪个目录下面运行这个命令 &#xff13;&#xff0e;vim kpd.c &#xff14;&#xff0e;输入 :cs add cscope.o…

Sanic服务启动失败,报错Cannot finalize with no routes defined

Sanic服务启动失败&#xff0c;记录解决方法 问题描述 Sanic服务启动失败&#xff0c;同样的代码和python版本在之前的win10系统上运行的好好的&#xff0c;换了台win11的机器就跑不起来了&#xff0c;不知道是系统原因还是因为换了执行pycharm等其他原因 在尝试启动时总是会…

打一波鸡血

在朋友圈看的一首诗&#xff0c;觉得很励志&#xff0c;如下&#xff1a;问题在于过度担心未来总是埋怨现在不断惋惜过往内心不知足想法逾现实行动很迟缓时间可贵青春难再审视脚下的路充实度日一日尚短庸碌混迹一日便长无妄的借口只会难上加难脚踏实地走才能遇难成祥守住时光用…

【Pytorch神经网络理论篇】 12 卷积神经网络实现+卷积计算的图解

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

vim 函数列表插件

&#xff11;&#xff0e;apt-get install exuberant-ctags &#xff12;&#xff0e;unzip taglist_42.zip  把解压出来的文件放到 /home/weiqifa(自己的用户名)/.vim/  资源下载&#xff1a; http://download.csdn.net/detail/weiqifa0/9137283&#xff13;&#xff0e;s…

【Pytorch神经网络实战案例】09 使用卷积提取图片的轮廓信息(手动模拟Sobel算子)

1 载入图片并显示 import matplotlib.pyplot as plt import matplotlib.image as mpimg import torch import torchvision.transforms as transforms import os os.environ["KMP_DUPLICATE_LIB_OK"]"TRUE" ### 1 载入图片并显示 myimg mpimg.imread(img.…

jquery深入学习

的转载于:https://www.cnblogs.com/lizhiwei8/p/6417798.html

【Pytorch神经网络理论篇】 13 深层卷积神经网络介绍+池化操作+深层卷积神经网络实战

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

gulp 系统教程

移步: http://www.cnblogs.com/2050/p/4198792.html gulp外挂 加md5 版本号 自动合并图片并修改css的坐标 一个系统列子 gulp可以做哪些事情转载于:https://www.cnblogs.com/dhsz/p/6419383.html

Android 广播接收

问题&#xff1a;写了一个应用来验证我按下音量键时发送出来的广播&#xff0c;可是老是提示出错&#xff0c; 原因&#xff1a;我的整个应用只继承吧BroadcastReceive&#xff0c;没有实际的继承Activity所以总是出现各种问题&#xff0c;现在修改好&#xff0c;上传代码 http…

【Pytorch神经网络实战案例】10 搭建深度卷积神经网络

识别黑白图中的服装图案(Fashion-MNIST)https://blog.csdn.net/qq_39237205/article/details/123379997基于上述代码修改模型的组成 1 修改myConNet模型 1.1.1 修改阐述 将模型中的两个全连接层&#xff0c;变为全局平均池化层。 1.1.2 修改结果 ### 1.5 定义模型类 class m…

Service Worker,Web Worker,WebSocket的对比

Service Worker 处理网络请求的后台服务。适用于离线和后台同步数据或推送信息。不能直接和dom交互。通过postMessage方法交互。 Web Worker 模拟多线程&#xff0c;允许复杂计算功能的脚本在后台运行而不会阻碍到其他脚本的运行。适用于处理器占用量大而又不阻碍的情形。不能直…

MTK 升级USB问题

问题&#xff1a;我们的开发环境是ubuntu里面安装xp ,经常是xp下没有正常识别preload模式下的usb.这样肯定不能升级不了。 设置&#xff1a;MTK preload下的USB vid:0e8d pid:2000 revion 0100 知道这几个值了&#xff0c;在usb配置里面增加这个筛选项就可以了。

JAVA 8 StreamAPI 和 lambda表达式 总结(一)--lambda表达式

这些天看见另一本好书《给大忙人看的Java SE 8》&#xff0c;其中的新特性 StreamAPI 和 lambda表达式 是之前jdk没有提供的新特性&#xff0c;也是jdk8 重要的更新内容&#xff0c;我会总结一下它们的用法&#xff0c;更详细的参见书本。 lambda表达式的概念 人对一个概念的理…

【Pytorch神经网络理论篇】 14 过拟合问题的优化技巧(一):基本概念+正则化+数据增大

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

MTK 8127平台使用busybox

一、什么是BusyBox &#xff1f; BusyBox 是标准 Linux 工具的一个单个可执行实现。BusyBox 包含了一些简单的工具&#xff0c;例如 cat 和 echo&#xff0c;还包含了一些更大、更复杂的工具&#xff0c;例如 grep、find、mount 以及 telnet。有些人将 BusyBox 称为 Linux 工具…

MediaPlayer 播放视频的方法

MediaPlayer mediaPlayer new MediaPlayer(); mediaPlayer.reset();//重置为初始状态 mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDisplay(surfaceView.getHolder());//设置画面显示为surfaceView mediaPlayer.setDataSource("/mnt/sdc…