我有一个数组a = [1, 2, 3, 4, 5, 6]
和b = [1, 3, 5]
,我想映射a
,以便a
中的每个元素都在b
之间b
中的元素将被映射到a
的索引,该索引是a = 1 -> 0 because a <= first element of b
a = 2 -> 1 because b[0] < 2 <= b[1] and b[1] = 3
a = 3 -> 1
a = 4 -> 2 because b[1] < 4 <= b[2]
所包含的上限。不是单词中的最佳解释,但这里是一个示例< / p>
f(a, b) = [0, 1, 1, 2, 2, 2]
所以我想要的最终产品是 import arpa
import ifaddrs
class func getBothIPAddresses() -> [AnyHashable: Any] {
let WIFI_IF: String = "en0"
let KNOWN_WIRED_IFS: [Any] = ["en2", "en3", "en4"]
let KNOWN_CELL_IFS: [Any] = ["pdp_ip0", "pdp_ip1", "pdp_ip2", "pdp_ip3"]
let UNKNOWN_IP_ADDRESS: String = ""
var addresses: [AnyHashable: Any] = ["wireless": UNKNOWN_IP_ADDRESS, "wired": UNKNOWN_IP_ADDRESS, "cell": UNKNOWN_IP_ADDRESS]
var interfaces: ifaddrs? = nil
var temp_addr: ifaddrs? = nil
var success: Int = 0
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(interfaces)
if success == 0 {
// Loop through linked list of interfaces
temp_addr = interfaces
while temp_addr != nil {
if temp_addr?.ifa_addr == nil {
continue
}
if temp_addr?.ifa_addr?.sa_family == AF_INET {
// Check if interface is en0 which is the wifi connection on the iPhone
if (String(utf8String: temp_addr?.ifa_name) == WIFI_IF) {
// Get NSString from C String
addresses["wireless"] = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
}
// Check if interface is a wired connection
if KNOWN_WIRED_IFS.contains(String(utf8String: temp_addr?.ifa_name)) {
addresses["wired"] = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
}
// Check if interface is a cellular connection
if KNOWN_CELL_IFS.contains(String(utf8String: temp_addr?.ifa_name)) {
addresses["cell"] = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
}
}
temp_addr = temp_addr?.ifa_next
}
}
// Free memory
freeifaddrs(interfaces)
return addresses
}
我知道我可以循环并解决它,但我想知道在pandas / numpy中是否有一种聪明,快速(矢量化)的方法
答案 0 :(得分:7)
使用python的bisect
模块:
from bisect import bisect_left
a = [1, 2, 3, 4, 5, 6]
b = [1, 3, 5]
def f(_a, _b):
return [bisect_left(_b, i) for i in _a]
print(f(a, b))
bisect - 数组平分算法
此模块支持按排序顺序维护列表,而无需在每次插入后对列表进行排序。对于具有昂贵比较操作的长项目列表,这可以是对更常见方法的改进。该模块称为bisect,因为它使用基本的二分算法来完成其工作。源代码作为算法的工作示例可能是最有用的(边界条件已经正确!)。
提供以下功能:
bisect.bisect_left(a, x, lo=0, hi=len(a))
在 a 中找到 x 的插入点,以维护排序顺序。参数 lo 和 hi 可用于指定应考虑的列表的子集;默认情况下,使用整个列表。如果 x 已存在于 a 中,则插入点将位于任何现有条目之前(左侧)。 假设 a 已经排序,返回值适合用作
list.insert()
的第一个参数。返回的插入点 i 将数组 a 分成两半,左侧为
all(val < x for val in a[lo:i])
,右侧为all(val >= x for val in a[i:hi])
答案 1 :(得分:2)
bisect更快:解决方案假定列表已排序
a = [1, 2, 3, 4, 5, 6]
b = [1, 3, 5]
inds=[min(bisect_left(b,x),len(b)-1) for x in a]
返回
[0, 1, 1, 2, 2, 2]