提问人:Seto 提问时间:10/12/2023 最后编辑:Seto 更新时间:10/14/2023 访问量:138
Ruby 复杂字符串数组到 float 数组
Ruby complex strings array to array of float
问:
我正在尝试将这个(相当复杂的)浮点字符串数组转换为浮点数组,但没有运气:
[ 5.85142857 6.10684807 6.15328798 6.31582766 6.96598639
7.61614512 7.87156463 8.73070295 9.38086168 9.65950113
10.51863946 12.07437642 12.32979592 13.39791383 13.63011338
13.86231293 14.09451247 14.72145125 14.97687075 15.85922902 ]
我试过什么:
def onset_string_to_array(onset)
# Remove the brackets.
onset = onset.tr('[]', '')
# Strip whitespace.
onset = onset.strip
# Split by newline character.
onset_lines = onset.split("\n")
# loop through each line.
onset_array = []
onset_array.push *onset_lines.map do |line|
# Split by space character.
line_array = line.split
# Return one float per line.
line_array.map(&:to_f)
end
onset_array
end
给我这个:
[
"0.53405896 0.7662585 0.99845805 1.20743764 1.41641723",
" 1.64861678 1.85759637 2.32199546 3.43655329 3.57587302",
" 4.08671202 4.7600907 4.99229025 5.87464853 6.52480726",
" 6.78022676 7.66258503 8.33596372 9.4737415 10.12390023",
" 10.35609977 10.750839 11.2152381 11.88861678 12.14403628",
" 12.60843537 12.84063492 13.04961451 13.69977324 13.95519274",
" 14.11773243 14.58213152 14.79111111 15.4644898 15.69668934",
" 16.60226757 17.27564626 17.5078458 18.39020408 19.06358277",
## More lines...
" 126.54875283 127.45433107 129.03328798 129.21904762 130.77478458",
" 131.00698413 131.86612245 132.81814059 133.35219955 134.55963719",
" 135.14013605"
]
我想要得到什么:
[ 0.53405896, 0.7662585, 0.99845805, 1.20743764, 1.41641723, 1.64861678, ...]
有什么线索吗?
答:
0赞
user229044
10/12/2023
#1
你已经点亮并剥离了前导/拖曳的空格,但在那之后,你就走上了一条不必要的复杂道路。[]
只需调用 ,默认情况下,它将贪婪地匹配空格作为其分隔符:split
str = '[ 5.85142857 6.10684807 6.15328798 6.31582766 6.96598639
7.61614512 7.87156463 8.73070295 9.38086168 9.65950113
10.51863946 12.07437642 12.32979592 13.39791383 13.63011338
13.86231293 14.09451247 14.72145125 14.97687075 15.85922902 ]'
str.tr('[]', '').strip.split.map(&:to_f)
至于为什么你的代码会失败,你正在将一个数组数组分散到你的初始数组上,这意味着你从来没有真正展平它。
如果由于某种原因,您必须避免通过正则表达式拆分整个字符串,而是逐行拆分,则应跳过 而只使用 :array.push(*other_array.map)
flat_map
str = '5.85142857 6.10684807 6.15328798 6.31582766 6.96598639
7.61614512 7.87156463 8.73070295 9.38086168 9.65950113
10.51863946 12.07437642 12.32979592 13.39791383 13.63011338
13.86231293 14.09451247 14.72145125 14.97687075 15.85922902'
str.lines.flat_map { |line| line.split.map(&:to_f) }
任一选项都会生成您想要的浮动平面列表:
[5.85142857,
6.10684807,
6.15328798,
6.31582766,
6.96598639,
7.61614512,
7.87156463,
8.73070295,
9.38086168,
9.65950113,
10.51863946,
12.07437642,
12.32979592,
13.39791383,
13.63011338,
13.86231293,
14.09451247,
14.72145125,
14.97687075,
15.85922902]
评论
1赞
engineersmnky
10/12/2023
或str.scan(/\d+\.\d+/).map(&:to_f)
2赞
user229044
10/12/2023
@engineersmnky 无论哪种方式。在空格上拆分需要不太复杂的正则表达式并考虑 ,并且不必生成逐渐复杂的正则表达式。1
.1
-1.0
1e6
2赞
ShadowRanger
10/12/2023
你在这里根本不需要正则表达式。 可能会变成(假设没有人在乱搞),或者如果你想防止乱搞,。Ruby 在这里与 Python 不同;如果你做了一个无限制,并且要拆分的分隔符是 ,它会在空格运行时拆分(其中 Python 区分 和 ,只有前者得到特殊的空格运行处理)。.split(/\s+/)
.split
$;
$;
.split(' ')
split
' '
.split()
.split(' ')
0赞
user229044
10/12/2023
@ShadowRanger 当然,你是对的。应该尝试一下,但几乎任何其他语言都是非常不明显的行为。
0赞
ShadowRanger
10/12/2023
@user229044:是的,我今天早些时候碰到的和一样,而且是......相当令人惊讶。没有参数的行为是“在空格上运行时拆分”,并不是那么不直观(即使它与显式分隔符的行为不一致,就像在 Python 中一样),但行为方式相同,在不是空格字符的东西上拆分?非常奇怪的选择。.split
.split(' ')
.split(' ')
4赞
mechnicov
10/12/2023
#2
要解析此字符串,您可以:
onset.delete('[]').split.map(&:to_f)
(1)首先删除括号,(2)然后用空格将字符串拆分为子字符串,(3)最后转换为浮点数
onset =
'[ 5.85142857 6.10684807 6.15328798 6.31582766 6.96598639
7.61614512 7.87156463 8.73070295 9.38086168 9.65950113
10.51863946 12.07437642 12.32979592 13.39791383 13.63011338
13.86231293 14.09451247 14.72145125 14.97687075 15.85922902 ]'
onset.delete('[]').split.map(&:to_f)
# =>
# [5.85142857,
# 6.10684807,
# 6.15328798,
# 6.31582766,
# 6.96598639,
# 7.61614512,
# 7.87156463,
# 8.73070295,
# 9.38086168,
# 9.65950113,
# 10.51863946,
# 12.07437642,
# 12.32979592,
# 13.39791383,
# 13.63011338,
# 13.86231293,
# 14.09451247,
# 14.72145125,
# 14.97687075,
# 15.85922902]
顺便说一句,Ruby 有内置的方法从字符串中获取行,你不需要用换行符拆分它,只需使用string.lines
评论
0赞
ShadowRanger
10/12/2023
需要明确的是,没有参数(和默认值)会在任何类型的空格的序列(“运行”)上拆分,而不仅仅是空格字符。这就是你在这里想要的,将换行符和空格字符及其混合物视为一个要拆分的东西,而不是在组件之间获得空字符串,或者只在空格或换行符上拆分。.split
$;
0赞
Cary Swoveland
10/12/2023
onset[1..-2]
是 的替代方法。onset.delete('[]')...
0赞
mechnicov
10/12/2023
@CarySwoveland我最初想过,但我们不知道这个结构是什么样子的,谁知道最后可能是']'。所以出于某种原因,我下定决心,决定而不是初步的喜欢delete
strip
onset.strip[1..-2].split.map(&:to_f)
1赞
Cary Swoveland
10/12/2023
“所以出于某种原因,我下定了决心......”是我经常做的事情,通常是非理性的......
1赞
Cary Swoveland
10/12/2023
#3
我假设
str = "[ 5.85142857 6.10684807 6.15328798 6.31582766 6.96598639\n 7.61614512 7.87156463 8.73070295 9.38086168 9.65950113\n 10.51863946 12.07437642 12.32979592 13.39791383 13.63011338\n 13.86231293 14.09451247 14.72145125 14.97687075 15.85922902 ]".
在这种情况下,你可以写
str.lines.map { |line| line.scan(/\d+\.\d+/).map(&:to_f) }
#=> [[ 5.85142857, 6.10684807, 6.15328798, 6.31582766, 6.96598639],
# [ 7.61614512, 7.87156463, 8.73070295, 9.38086168, 9.65950113],
# [10.51863946, 12.07437642, 12.32979592, 13.39791383, 13.63011338],
# [13.86231293, 14.09451247, 14.72145125, 14.97687075, 15.85922902]]
例如,当
line = "10.51863946, 12.07437642, 12.32979592, 13.39791383, 13.63011338"
然后
arr = line.scan(/\d+\.\d+/)
#=> ["10.51863946", "12.07437642", "12.32979592", "13.39791383", "13.63011338"]
arr.map(&:to_f)
#=> [10.51863946, 12.07437642, 12.32979592, 13.39791383, 13.63011338]
如果“扁平化”是指你希望生成一个包含 20 个浮点数的数组,而不是由四个数组组成的数组,每个数组包含五个浮点数(如上所述),则可以将
str.scan(/\d+\.\d+/).map(&:to_f)
#=> [ 5.85142857, 6.10684807, 6.15328798, 6.31582766, 6.96598639,
# 7.61614512, 7.87156463, 8.73070295, 9.38086168, 9.65950113,
# 10.51863946, 12.07437642, 12.32979592, 13.39791383, 13.63011338,
# 13.86231293, 14.09451247, 14.72145125, 14.97687075, 15.85922902]
评论
0赞
Chris
10/12/2023
如果并非所有数字都有小数位,则可能需要将正则表达式的部分设为可选。\.\d+
0赞
Cary Swoveland
10/12/2023
谢谢,@Chris,可以做到,但是,给定这个例子,与浮点数混合在一起的整数(即它的字符串表示)可能是坏数据,所以以我所拥有的,我不会标记它,并且按照你的建议进行更改会把坏的看作是好的。双输双赢。在真正的应用程序中可以完成更多工作。
评论
"10.51863946"
10.51863946