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


猜你喜欢
- ipad的goodreader对JS文件支持不太好,虽然可以读取它但总是无法退出,回不了goodreader的主界面,因此我需要把js文件批
- java后台相关问题一,程序包lombok不存在通常报这个错误,是因为,我们的开发者工具idea没有安装lombok库导致的解决办法如下:提
- 函数原型参数介绍mode (torch.nn.Module, torch.jit.ScriptModule or torch.jit.Scr
- 一个简单的tokenizer分词(tokenization)任务是Python字符串处理中最为常见任务了。我们这里讲解用正则表达式构建简单的
- 程序没有改动过运行一直正常,突然有一天同事告知出现错误了。经过检查发现传递的数据中出现了#等特殊字符,浏览器只取到#号前面的数据,后面的被截
- 如何提取JSON数据指定内容假设我们要获取'pic_str'里的数据JSON数据{'err_no': 0,
- 1.尽量不要对列名进行函数处理。而是针对后面的值进行处理例如where col1 = -5的效率比where -col1=5的效率要高因为后
- 下面两个函数实现了对字符串中数字的判断。function isnaw(str) f
- 一。初识单元测试1)定义:单元:函数或者是类单元测试:测试类或者函数python内置的单元测试框架:unittest2)单元测试的意义好处:
- Jupyter Notebook读取csv文件失败1.IndentationError: expected an indented bloc
- 安装库位置和显示方式简单总结:一、位置的不同 1.自带库在环境的 lib\\os.py&nb
- whoosh的官方介绍:http://whoosh.readthedocs.io/en/latest/quickstart.html因为做的
- 解决这个问题的办法有三种: 1. 增加 MySQL 的 wait_timeout 属性的值。 修改 /etc/mysql/my.cnf文件,
- 最近朋友需要一个可以识别图片中的文字的程序,以前做过java验证码识别的程序;刚好最近在做一个python项目,所以顺便用Python练练手
- 这个框架主要还是思想,之后,,,还是创建项目好了,1.新建一个项目新建一个maven,并且选择webapp类型。2.点击next选项这里面的
- 今天请各位读者朋友欣赏用 Python 实现的鲜花盛宴,你准备好了吗?90 行代码即可实现一棵美丽的鲜花盛开树。小编也是鲜花爱护协会者之一,
- 使用SQLSERVER的应该经常遇到“Unable to read local eventlog (reason:事件日志文件已在读取时间更
- -- 1. 查看被锁的表SELECT p.spid, a.serial#, c.object_name, b.session_id, b.o
- 文件数据读写读写文件,本质上是请求操作系统打开一个文件对象,然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这
- 需求通过分析nginx访问日志,获取每个接口响应时间最大值、最小值、平均值及访问量。实现原理将nginx日志uriuriupstream_r