pandas 使用merge实现百倍加速的操作
作者:shywang001 发布时间:2022-06-11 08:22:28
对于非连续数据集,数据可视化时候需要每七天一个采样点。要求是选择此前最新的数据作为当日的数据展示,譬如今天是2019-06-18,而数据集里只有2019-06-15,那就用2019-06-15的数据作为2019-06-18的数据去描点。
每七天一个采样点,会使得每天展示所选的数据都会有所不同。当时间往后推移一天,日期为2019-06-19,那么最新数据点从2019-06-19开始,第二个就是2019-06-12。这里就需要一个算法来快速的根据当前日期去选出(填充)一系列数据供数据可视化之用。
一个非常直接的实现方法:
先生成一串目标时间序列,从某个开始日到今天为止,每七天一个日期。
把这些日期map到数据集的日期, Eg. {“2019-06-18”:“2019-06-15”…} 。
把map到的数据抽出来用pd.concat接起来。
代码如下:
target_dates = pd.date_range(end=now, periods=100, freq="7D")
full_dates = pd.date_range(start, now).tolist()
org_dates = df.date.tolist()
last_date = None
for d in full_dates:
if d in org_dates:
date_map[d] = d
last_date = d
elif last_date is not None:
date_map[d] = last_date
else:
continue
new_df = pd.DataFrame()
for td in target_dates:
new_df = pd.concat([new_df, df[df["date"]==date_map[td]])
这样的一个算法处理一个接近千万量级的数据集上大概需要十多分钟。仔细检查发现,每一次合并的dataframe数据量并不小,而且总的操作次数达到上万次。
所以就想如何避免高频次地使用pd.concat去合并dataframe。
最终想到了一个巧妙的方法,只需要修改一下前面的第三步,把日期的map转换成dataframe,然后和原始数据集做merge操作就可以了。
target_dates = pd.date_range(end=now, periods=100, freq="7D")
full_dates = pd.date_range(start, now).tolist()
org_dates = df.date.tolist()
last_date = None
for d in full_dates:
if d in org_dates:
date_map[d] = d
last_date = d
elif last_date is not None:
date_map[d] = last_date
else:
continue
#### main change is from here #####
date_map_list = []
for td in target_dates:
date_map_list.append({"target_date":td, "org_date":date_map[td]})
date_map_df = pd.DataFrame(date_map_list)
new_df = date_map_df.merge(df, left_on=["org_date"], right_on=["date"], how="inner")
改进之后,所有的循环操作都在一个微数量级上,最后一个merge操作得到了所有有用的数据,运行时间在5秒左右,大大提升了性能。
补充:Pandas DataFrames 中 merge 合并的坑点(出现重复连接键)
在我的实际开发中遇到的坑点,查阅了相关文档 总结一下
left = pd.DataFrame({'A': [1, 2], 'B': [2, 2]})
right = pd.DataFrame({'A': [4, 5, 6], 'B': [2, 2, 2]})
result = pd.merge(left, right, on='B', how='outer')
警告:在重复键上加入/合并可能导致返回的帧是行维度的乘法,这可能导致内存溢出。在加入大型DataFrame之前,重复值。
检查重复键
如果知道右侧的重复项DataFrame但希望确保左侧DataFrame中没有重复项,则可以使用该 validate='one_to_many'参数,这不会引发异常。
pd.merge(left, right, on='B', how='outer', validate="one_to_many")
# 打印的结果:
A_x B A_y
0 1 1 NaN
1 2 2 4.0
2 2 2 5.0
3 2 2 6.0
参数:
validate : str, optional
If specified, checks if merge is of specified type.
“one_to_one” or “1:1”: check if merge keys are unique in both left and right datasets.
“one_to_many” or “1:m”: check if merge keys are unique in left dataset.
“many_to_one” or “m:1”: check if merge keys are unique in right dataset.
“many_to_many” or “m:m”: allowed, but does not result in checks.
官方文档连接:
Pandas文档中提及 merge
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。
来源:https://blog.csdn.net/shywang001/article/details/92794219
猜你喜欢
- 一、传入的参数类型要求不同:1、 file.write(str)需要传入一个字符串做为参数,否则会报错。write( "字符串&q
- 前言metrics用于判断模型性能。度量函数类似于损失函数,只是度量的结果不用于训练模型。可以使用任何损失函数作为度量(如logloss等)
- 本文实例为大家分享了python手写均值滤波的具体代码,供大家参考,具体内容如下原理与卷积类似,设置一个n*n的滤波模板,滤波模板内的值累加
- 一、自动化测试的概念性能系统负载能力稳定性过载操作下的系统瓶颈自动化测试,使用程序代替人工,可以提高测试效率性,自动化测试能自动化使用代码模
- 环境: Python3 + windows。开发工具:Anaconda + Jupyter / VS Code。学习效果:1.认识爬虫 /
- 1、注册时验证数据库用户名是否存在。 2、输入密码时提示密码强度和验证2次密码输入是否一样。 3、注册时验证数据库联系邮箱是否存在。 4、注
- 前言老早就看到新闻员工通过人脸识别监控老板来摸鱼。有时候摸鱼太入迷了,经常在上班时间玩其他的东西被老板看到。自从在咸鱼上淘了一个树莓派3b,
- 有过网页制作经验的朋友一定知道:一般来讲,把表格的边框定义为1px时,即border=1,而实际上是2
- 实验环境:windows 7,anaconda 3(python 3.5),tensorflow(gpu/cpu)函数介绍:所用函数为six
- * 页爬取是爬虫学习中的一个难点。本文将以知名插画网站pixiv为例,简要介绍 * 页爬取的方法。写在前面本代码的功能是输入画师的pixi
- Python的matplotlib模块中的errorbar函数可以绘制误差棒图,本次主要绘制不带折线的误差棒图。1.基本参数errorbar
- 今晚想实现这样一个功能:将输入字符串中的字母 “i” 变成字母 “p”。当时想的很简单,直接用for循环遍历,然后替代,出问题的代码如下:n
- os:windows前提:Python,selenium,IEDriverServer.exe,ie浏览器首先安装Python2.7安装成功
- 下面是我已经证实可用的自动备份的方法. 1、打开企业管理器->管理->sql server代理 2、新建一个作业,作业名称随便取
- Python 三元运算符Python 三元运算符用于根据条件选择两个值之一。它是 if-else 语句的一个缩影,它将两个值之一分配给一个变
- Celery是一个异步的任务队列(也叫做分布式任务队列),一个简单,灵活,可靠的分布式系统,用于处理大量消息,同时为操作提供维护此类系统所需
- 没人愿意等待。所以,没有访问者真的能够忍受一个打开速度极慢的网站。但是,网页打开速度到底对用户行为有什么影响,恐怕没几个人能够说清楚吧。前几
- 使用穷举法求两个数的最大公约数for m in range (0,2): a = int(input("
- 这篇论坛文章(赛迪网技术社区)详细讲解了SQL Server海量数据导入的最快方法,更多内容请参考下文:最近做某项目的数据库分析,要实现对海
- 我们都知道Jupyter notebook更换主题后看着会很舒服,但是有个问题主题更换后工具栏不显示了。usename$ jt -lAvai