2015-04-03 139 views
2

我有一个函数内部的数据帧DataArray中不区分大小写的匹配:返回匹配的索引值

using DataFrames 

myservs = DataFrame(serverName = ["elmo", "bigBird", "Oscar", "gRover", "BERT"], 
        ipAddress = ["12.345.6.7", "12.345.6.8", "12.345.6.9", "12.345.6.10", "12.345.6.11"]) 
myservs 
5x2 DataFrame 
| Row | serverName | ipAddress  | 
|-----|------------|---------------| 
| 1 | "elmo"  | "12.345.6.7" | 
| 2 | "bigBird" | "12.345.6.8" | 
| 3 | "Oscar" | "12.345.6.9" | 
| 4 | "gRover" | "12.345.6.10" | 
| 5 | "BERT"  | "12.345.6.11" | 

我怎么能写出函数采取所谓server一个参数,不区分大小写的匹配myservs[:serverName] DataArray中的server参数,并返回匹配的相应ipAddress

在该R这可以通过使用

myservs$ipAddress[grep("server", myservs$serverName, ignore.case = T)] 

我不希望如果有人使用ElMoElmo作为server,或者如果serverName保存为elmoELMO它就能完成。

回答

3

我引用如何完成任务R和尝试使用DataFrames PKG做到这一点,但我只能这样做,因为我是从R来和我刚开始学习Julia。我问了很多问题,从同事和下面就是我们想出了:

这个任务,如果我是停在Rvectors思维干净多了。 Julia运行足够快的循环迭代。

即使如此,循环不会是最好的解决方案。我被告知要查看 Dicts(例如,检查here)。 Dict()zip()haskey()get()吹了我的脑海。这些有很多应用。

我的解决方案甚至不需要使用DataFrames PKG,而是 使用Julia的MatrixArray数据表示。通过使用let 我们保持全球环境无任何混乱,并且服务器名称/ ip 列表对于仅运行 函数的用户来说处于隐藏状态。

在示例代码中,我每次都重新创建服务器矩阵,但在现实/实践中,我将拥有一个权限受限的分隔文件,每次都会读取。由于分隔文件很小,所以现在可以,但这可能不是有效的或最好的方式。

# ONLY ALLOW THE FUNCTION TO BE SEEN IN THE GLOBAL ENVIRONMENT 
let global myIP 

    # SERVER MATRIX 
    myservers = ["elmo" "12.345.6.7"; "bigBird" "12.345.6.8"; 
       "Oscar" "12.345.6.9"; "gRover" "12.345.6.10"; 
       "BERT" "12.345.6.11"] 

    # SERVER DICT 
    servDict = Dict(zip(pmap(lowercase, myservers[:, 1]), myservers[:, 2])) 

    # GET SERVER IP FUNCTION: INPUT = SERVER NAME; OUTPUT = IP ADDRESS 
    function myIP(servername) 
    sn = lowercase(servername) 
    get(servDict, sn, "That name isn't in the server list.") 
    end 
end 

​# Test it out 
myIP("SLIMEY") 
​#>​"That name isn't in the server list." 

myIP("elMo"​) 
#>​"12.345.6.7" 
+1

您可能还想探索Julia的[DataStructures.jl](https://github.com/JuliaLang/DataStructures.jl)以查找其他更高性能的查找。 – rickhg12hs 2015-04-11 17:27:04

+0

谢谢你的建议。迄今为止看起来很棒。 – 2015-04-12 20:59:24

2

这里有一种方法:

julia> using DataFrames 

julia> myservs = DataFrame(serverName = ["elmo", "bigBird", "Oscar", "gRover", "BERT"], 
          ipAddress = ["12.345.6.7", "12.345.6.8", "12.345.6.9", "12.345.6.10", "12.345.6.11"]) 
5x2 DataFrames.DataFrame 
| Row | serverName | ipAddress  | 
|-----|------------|---------------| 
| 1 | "elmo"  | "12.345.6.7" | 
| 2 | "bigBird" | "12.345.6.8" | 
| 3 | "Oscar" | "12.345.6.9" | 
| 4 | "gRover" | "12.345.6.10" | 
| 5 | "BERT"  | "12.345.6.11" | 

julia> grep{T <: String}(pat::String, dat::DataArray{T}, opts::String = "") = Bool[isna(d) ? false : ismatch(Regex(pat, opts), d) for d in dat] 
grep (generic function with 2 methods) 

julia> myservs[:ipAddress][grep("bigbird", myservs[:serverName], "i")] 
1-element DataArrays.DataArray{ASCIIString,1}: 
"12.345.6.8" 

编辑

grep作品在我的平台上更快。

julia> function grep{T <: String}(pat::String, dat::DataArray{T}, opts::String = "") 
      myreg = Regex(pat, opts) 
      return convert(Array{Bool}, map(d -> isna(d) ? false : ismatch(myreg, d), dat)) 
     end 
+0

谢谢。这是有效的,这是你写的一个很棒的grep函数,但是我真的在寻找关于如何使用一个只有一个参数并返回IP的函数的方法。例如,'server_ip_address(“GROVER”)或'server_ip_address(“grover”)'都会返回'“12.345.6.10”'。我来自R,对Julia来说很新,所以我不知道在Julia做到这一点的最佳方式。 – 2015-04-03 21:22:50

+0

我模仿了我从你的例子'R'的答案。我不确定你提出的功能是什么意思。例如,函数如何知道要使用什么'DataFrame'和列?还是你想为你提供的情况定义一个特定的功能? – rickhg12hs 2015-04-03 21:56:17

+0

我也注意到,如果你需要更高的性能,预计算'Regex'会大大加快'grep'的速度。 – rickhg12hs 2015-04-06 18:04:07