python - 基于多个条件(lt、gt 测试标准)将数据帧索引作为值分配给另一个数据帧
问题描述
我有一个看起来像这样的数据框(它表示 2D 空间中的区域;请注意它们重叠,这没关系):
>>> zones = pd.DataFrame(dict(
minx=[-10, -10, -5],
maxx=[10, 10, 5],
miny=[-10, 0, 0],
maxy=[10, 10, 10],
), index=range(1,4))
>>> zones.index.name = "zone"
>>> zones
minx maxx miny maxy
zone
1 -10 10 -10 10
2 -10 10 0 10
3 -5 5 0 10
我有第二个有序对的数据框,如下所示(这里是随机数,因为它们并不重要):
>>> pairs = pd.DataFrame(list(zip((uniform(0, 10) for _ in range(10)), (uniform(0,10) for _ in range(10)))), index=range(1,11), columns=["cx", "cy"])
>>> pairs.index.name = "pair"
>>> pairs["zone"] = "??"
>>> pairs
cx cy zone
pair
1 8.405715 2.691102 ??
2 6.645482 1.843225 ??
3 4.123719 8.996641 ??
4 7.003991 9.695182 ??
5 7.296730 1.175356 ??
6 7.960617 9.503888 ??
7 7.694749 6.907869 ??
8 8.308742 5.439141 ??
9 6.404875 5.663983 ??
10 3.361129 3.123590 ??
我想根据第一个数据帧中的区域定义为每个 cx、cy 对填充此数据帧的“区域”系列。
我为此编写的代码如下。但是,我确信使用 pandas 有更好的方法(即,无需遍历zones
列)。应该怎么做?
for num, zone in zones.transpose().iteritems():
idx = (
(pairs.cx.gt(zone["minx"]))
& (pairs.cx.lt(zone["maxx"]))
& (pairs.cy.gt(zone["miny"]))
& (pairs.cy.lt(zone["maxy"]))
)
pairs.loc[idx, "zone"] = num
注意:最高的区域编号获胜。因此,例如,上面第二个表中的索引 5 具有近似的有序对 (7.3, 1.2),并且将落在区域 1、2 和 3 内。因此,它应该是区域 3。但是,索引 9 与 aop ( 6.4, 5.7) 位于 3 区之外,但在 1 区和 2 区之内。因此,应将其分配到 2 区。
解决方案
一点点改进使用numpy
广播
cx = pairs.cx.values
cy = pairs.cy.values
minx, maxx, miny, maxy = zones.T.values
s = (
pd.DataFrame(
(cx > minx[:, None])
& (cx < maxx[:, None])
& (cy > miny[:, None])
& (cy < maxy[:, None])
)
.mul(zones.index, axis=0)
.max()
)
s
0 2
1 2
2 2
3 3
4 2
5 3
6 2
7 3
8 3
9 2
dtype: int64
pairs["zone"]=s.values
推荐阅读
- .net - 我的c#visual studio项目编译时生成的dll文件太多
- android - 如何使用 Mockito 在 Android 中对 LocationListener 进行单元测试
- c++ - 为什么编译器将类函数作为非静态函数处理?
- java - 我创建了一个 testng.xml 文件,其中提到了我的所有类以进行回归测试套件运行,但并非所有类都通过该 xml 运行
- android - 由于切换另一个应用程序,我的应用程序区域设置正在更改
- xcode - 如何在 Xcode 中运行单个 UI 测试
- android - 由 ABI 拆分时的 .APK 名称之间的后缀/前缀/中间
- javascript - 如何检查帖子或属性是否已被查看(在每个会话中)
- javascript - 如何在fancybox的内容下方放置标题/标题?
- android - 如何确保 Android APK 支持 32 位和 64 位?