实战手记:如何用 pandas 搞定这种“既要又要”的筛选魔咒 别指望我教你那些“起初、其次、最终”的教科书式套路,实战里咱们才是最需求点烟火气的。今天不想整那些虚头巴脑的理论,直接上代码,咱们来聊聊如何在 `pandas` 里把两张表里的数据挑出来,条件是:既要工夫大于等于 2020 年 1 月 1 日,又要数值大于 100,别的啥都不管。 启动动手了,打开 `df1` 和 `df2`,别急着看代码,先看看这俩表长啥样。`df1` 是工夫维度的,大约是从 2020 年初一直滚到 2023 年底,每行代表一天或一年;`df2` 是数值维度的,里面全是乱七八糟的数值,有的年份没数据,有的年份数值都没超过 100。 先把 `df1` 里的“工夫列”拿出来,调成 datetime 类型。
这一步要是做错了,后面全蒙眼,故此得先确认类型。
然后对 `df2` 里的“数值列”做同样操作,确保都是 float64。
这一步看似好办,但数据类型乱飞的时候确实会卡壳,特别是工夫列有时候会混入整数,有时候又变成 float,搞不好还得先转个字符串再转回日期,别看废话,但有时候是救命稻草。 有了这两个“干净利落”的表,咱们就得凑合着篩选了。
实际上不需求啥复杂的 `merge` 要么 `apply`,直接两条链子就行。先 `filter` `df1`,把工夫挑出来,大于等于 2020 年 1 月 1 日那一批。
这时候你会看到 `df1` 变窄了,只剩下了那些在红线之后的日子。 接着 `filter` `df2`,把数值挑出来,大于 100 那一批。
这时候你就连不需求把 `df1` 和 `df2` 拼起来。直接把这两列,也就是 `df1['工夫列']` 和 `df2['数值列']` 拼起来加个 `+` 号,就能直接拿到结局。 实际上这第一步 `df1['工夫列'] > >= 2020-01-01` 和 `df2['数值列'] > 100` 实际上能够合并成一个字符串,比如 "time > 2020-01-01 AND num > 100",然后用 `&` 和 `|` 连接。
这样写起来更顺手一点,不过要注意逻辑搞反了,要是把大于和小于搞混了,结局准得让你笑掉大牙。 代码运行下来,有时候你会发现回的数据框有点怪,比如某些行既有值又有空值,要么数值列是 int64 而工夫列还是 datetime64 [ns],这种类型不匹配有时候会报错,提示不一致,这时候还得微调一下类型。
有时候 `filter` 出来的结局,工夫列是 numpy 对象,不是 standard 的类型,直接拿回去用 `isin` 要么 `where` 再过滤一次,别看有点绕,但有时候比代码报错还快。 为了验证一下效果,咱们造个具体的例子。假设有一批业务数据,2021 年 3 月 15 日是第一个达标的数据,而 2021 年 9 月 1 日才是第二个。
另外有些数据数值是整数,有些是浮点数。运行代码后,你看,正好就拿出了这两行:一行工夫大于等于 2020-01-01 且数值大于 100,另一行工夫大于等于...不对,什么的,这里有个坑。
要是 `df2` 里有一行数值等于 150,它会被包含进去;要是有一行数值等于 140,也会被包含进去。出于条件是“大于等于”,故此 100 和 140 都能被选中。但要是有一行数值是 99,就被排除了。 实际上有时候咱们不需求如此死板,要是条件特别复杂,比如要排除某些特定的标记列,要么要与此同时寻思两个表里的其他列,那就得寻思用 `merge` 要么 `concat` 把数据拼在一起,然后加条件。
比如把 `df1` 和 `df2` 拼起来,变成一个大表,然后对这个大表加一个条件,`df = df[df['time'] > 2020-01-01 & df['num'] > 100]`。 这时候你可能会问,为啥有时候 `filter` 出来的结局不是我们想要的?
是不是出于 `filter` 回的是 `copy` 要么 `selector`?实际上没难题,只要用 `.loc` 要么 `.iloc` 再切一次,就能拿到真正的切片。
有时候直接用 `loc` 写起来更快,比如 `result = df2[(df2['num'] > 100) & (df2['time'] > 2020-01-01)]`,这样逻辑上更清楚,也更好办读。 最终还得提一下,有时候筛选出来的数据,某些列的类型还是有点小难题,比如数值列变成了 int,变成 int 有时候在后续计算里会隐式转换,有时候又会报错。
这时候记得再跑一遍类型转换,要么用 `astype` 强制转成 float。 总的来说,用 `pandas` 做这种双条件筛选,核心就三件事:先搞定数据类型,再用 `filter` 要么 `loc` 切条件,最终别忘了检查一下类型。
要是代码报错,多半是数据类型不对,要么逻辑写反了。别被那些复杂的函数吓到,有时候最笨的方式反而是最好的,直接拼个字符串条件,跑起来往往是最快的。 记得,代码跑通了不代表就万事大吉,有时候数据里有重复行,要么某些列有缺失值,这时候还得再 `df.drop_duplicates()` 要么 `df.dropna()` 擦一擦,不然到时候跑模型要么分析时,数据脏了,全跑偏了。 希望今天的分享能帮你少走弯路,下次要是再遇到这种复杂的筛选任务,直接拿来试试吧,别死磕那些教科书里的条条框框,实战才是王道。


相关标签: