python:如果某个数字落在某个范围内,则返回该范围对应的字符串

时间:2015-04-20 12:09:05

标签: python range dataframe multiple-columns

我有一个带有一列数字的数据框(df1),比如说:

  • [[2,7,17​​]]

和另一个具有范围列表的数据帧(df2),由两列定义 - 起始位置(p1)和结束位置(p2)。此数据框中的每个范围在同一行的另一列中都有对应的字符串(名称),例如:

  • p1 [[1,6,11,20]]
  • p2 [[5,10,15,16]]
  • 姓名[[' A',' B'' C',' D']]

我需要找到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中找不到类似的东西。

提前谢谢你,请记住我是一个新手!

1 个答案:

答案 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]]是该号码所属的第一个(可能有几个)类别。