我有一个带有一列数字的数据框(df1),比如说:
和另一个具有范围列表的数据帧(df2),由两列定义 - 起始位置(p1)和结束位置(p2)。此数据框中的每个范围在同一行的另一列中都有对应的字符串(名称),例如:
我需要找到df1中的数字范围(A,B,C或D)。在这个例子中,2落在1和5之间,因此将返回' A'而7落在6和10之间,因此将返回' B' 11到15之间什么都没有,所以C'不会被退回,但D会在16到20之间返回。
注意:虽然A和B都在高于起始位置的位置结束(p1低于p2),但D从高于其结束的位置开始(p2低于p1)。我仍然希望在df1中将17调用为落在范围D内,即使范围是相反的。
尽管this文章似乎在java中提出了类似的问题,但除了this之外,我在python中找不到类似的东西。
提前谢谢你,请记住我是一个新手!
答案 0 :(得分:1)
这是一个有一些想法的草案。我用numpy。我使用了数组,但您可以使用问题中指定的列。
import numpy as np
df1 = np.array([2,7,17,0])
p1 = np.array([1,6,11,20])
p2 = np.array([5,10,15,16])
name = np.array(['A','B','C','D'])
result = []
for d in df1:
categories = np.logical_or(
np.logical_and(d >= p1, d <= p2),
np.logical_and(d <= p1, d >= p2))
result.append(name[categories[0]] if np.any(categories) else '')
print(result)
如果某个数字属于多个类别,则只返回一个。如果它不属于空,则返回一个空字符串(您可能更愿意返回None
)。
两个方向的范围由logical_or管理。
“技巧”是使用布尔数组寻址。 categories
是一个布尔数组(例如[True,False,False,False]),当且仅当数据在相应的类别中时,每个元素都为True:第一个元素True表示它在类别A中,等等
name[categories]
是一个包含name
的所有元素的数组,categories
中的对应元素为True。其他元素被剥离。
e.g。 np.array([1,2,3])[np.array([True, False, True])]
- &gt; array([1,3])
name[categories[0]]
是该号码所属的第一个(可能有几个)类别。