根据 Julia DataFrame 中的多个条件选择列
Selecting Columns Based on Multiple Criteria in a Julia DataFrame
我需要 select 根据来自数组的多个条件从 Julia 数据框中的单个列获取值。上下文:我试图格式化来自大型 Julia DataFrame 的数据以支持 PCA(主成分分析),因此我首先将原始数据拆分为一个分析矩阵和一个标签数组。到目前为止,这是我的代码(不起作用):
### Initialize source dataframe for PCA
dfSource=DataFrame(
colDataX=[0,5,10,15,5,20,0,5,10,30],
colDataY=[1,2,3,4,5,6,7,8,9,0],
colRowLabels=[0.2,0.3,0.5,0.6,0.0,0.1,0.2,0.1,0.8,0.0])
### Extract 1/2 of rows into analytical matrix
matSource=convert(Matrix,DataFrame(dfSource[1:2:end,1:2]))'
### Extract last column as labels
arLabels=dfSource[1:2:end,3]
### Select filtered rows
datGet=matSource[:,arLabels>=0.2 & arLabels<0.7][1,:]
print(datGet)
output> MethodError: no method matching...
在 print(datGet)
语句之前的最后一行,我收到一个 MethodError 指示与使用 &
逻辑相关的方法不匹配。我做错了什么?
此代码有效:
dfSource=DataFrame(
colDataX=[0,5,10,15,5,20,0,5,10,30],
colDataY=[1,2,3,4,5,6,7,8,9,0],
colRowLabels=[0.2,0.3,0.5,0.6,0.0,0.1,0.2,0.1,0.8,0.0])
matSource=convert(Matrix,DataFrame(dfSource[1:2:end,1:2]))'
arLabels=dfSource[1:2:end,3]
datGet=matSource[:,(arLabels.>=0.2) .& (arLabels.<0.7)][1,:]
print(datGet)
output> [0,10,0]
请注意括号 (arLabels.>=0.2)
和 (arLabels<0.7)
的使用,以及 .>=
和 .<
语法的使用(这会强制 Julia 遍历一个container/collection)。最后,也是最关键的(因为这是大多数人都忽略的部分),请注意使用 .&
代替 &
。点运算符让一切变得不同!
替代实现的一个小示例(也许您会发现查看 DataFrames.jl 内置的内容很有用):
# avoid materialization if dfSource is large
dfSourceHalf = @view dfSource[1:2:end, :]
lazyFilter = Iterators.filter(row -> 0.2 <= row[3] < 0.7, eachrow(dfSourceHalf))
matFiltered = mapreduce(row -> collect(row[1:2]), hcat, lazyFilter)
matFiltered[1, :]
(这不是针对速度进行优化,而是为了展示可能的情况,但它仍然比您的代码快几倍)
我需要 select 根据来自数组的多个条件从 Julia 数据框中的单个列获取值。上下文:我试图格式化来自大型 Julia DataFrame 的数据以支持 PCA(主成分分析),因此我首先将原始数据拆分为一个分析矩阵和一个标签数组。到目前为止,这是我的代码(不起作用):
### Initialize source dataframe for PCA
dfSource=DataFrame(
colDataX=[0,5,10,15,5,20,0,5,10,30],
colDataY=[1,2,3,4,5,6,7,8,9,0],
colRowLabels=[0.2,0.3,0.5,0.6,0.0,0.1,0.2,0.1,0.8,0.0])
### Extract 1/2 of rows into analytical matrix
matSource=convert(Matrix,DataFrame(dfSource[1:2:end,1:2]))'
### Extract last column as labels
arLabels=dfSource[1:2:end,3]
### Select filtered rows
datGet=matSource[:,arLabels>=0.2 & arLabels<0.7][1,:]
print(datGet)
output> MethodError: no method matching...
在 print(datGet)
语句之前的最后一行,我收到一个 MethodError 指示与使用 &
逻辑相关的方法不匹配。我做错了什么?
此代码有效:
dfSource=DataFrame(
colDataX=[0,5,10,15,5,20,0,5,10,30],
colDataY=[1,2,3,4,5,6,7,8,9,0],
colRowLabels=[0.2,0.3,0.5,0.6,0.0,0.1,0.2,0.1,0.8,0.0])
matSource=convert(Matrix,DataFrame(dfSource[1:2:end,1:2]))'
arLabels=dfSource[1:2:end,3]
datGet=matSource[:,(arLabels.>=0.2) .& (arLabels.<0.7)][1,:]
print(datGet)
output> [0,10,0]
请注意括号 (arLabels.>=0.2)
和 (arLabels<0.7)
的使用,以及 .>=
和 .<
语法的使用(这会强制 Julia 遍历一个container/collection)。最后,也是最关键的(因为这是大多数人都忽略的部分),请注意使用 .&
代替 &
。点运算符让一切变得不同!
替代实现的一个小示例(也许您会发现查看 DataFrames.jl 内置的内容很有用):
# avoid materialization if dfSource is large
dfSourceHalf = @view dfSource[1:2:end, :]
lazyFilter = Iterators.filter(row -> 0.2 <= row[3] < 0.7, eachrow(dfSourceHalf))
matFiltered = mapreduce(row -> collect(row[1:2]), hcat, lazyFilter)
matFiltered[1, :]
(这不是针对速度进行优化,而是为了展示可能的情况,但它仍然比您的代码快几倍)