kdb+/q:给定要更新的键和值列表的快速矢量更新
kdb+/q: Fast vector update given a list of keys and values to be updated
给定一个 ids/keys 列表和一组常量列的相应值:
q)ikeys: 1 2 3 5;
q)ivals: 100 100.5 101.5 99.5;
更新以下 table 中的 `toupd 列的最快方法是什么,以便将与给定 ikeys 匹配的行更新为 ivals:i.e.[= 中的新值13=]
q) show tab;
ikeys | `toupd `noupd
------|--------------
1 | 0.5 1
2 | 100.5 2
3 | 500.5 4
4 | 400.5 8
5 | 400.5 16
6 | 600.5 32
7 | 700.5 64
更新为:
q) show restab;
ikeys | `toupd `noupd
------|--------------
1 | 100 1
2 | 100.5 2
3 | 101.5 4
4 | 400.5 8
5 | 99.5 16
6 | 600.5 32
7 | 700.5 64
此外,是否有一种规范的方法可以以这种方式更新多个列。
谢谢
这里有两种不同的方法。
tab lj ([ikeys] toupd: ivals)
或
m: ikeys
update toupd: ivals from tab where ikeys in m
我相信还有很多方法。如果您想找出最适合您的目的(和您的数据)的方法,请尝试对大型表使用 q)\t:1000 yourCodeHere
并查看最适合您的方法。
至于哪个是多列的规范方式,我想应该是更新,但这是个人喜好问题,最快的就可以了。
字典也是给定映射更新值的常用方法。使用 ikeys 列索引字典给出新值,然后我们用旧的 toupd 列值填充空值。
q)show d:ikeys!ivals
1| 100
2| 100.5
3| 101.5
5| 99.5
q)update toupd:toupd^d ikeys from tab
ikeys| toupd noupd
-----| -----------
1 | 100 1
2 | 100.5 2
3 | 101.5 4
4 | 400.5 8
5 | 99.5 16
6 | 600.5 32
7 | 700.5 64
还值得注意的是,where 子句的更新条件并不能保证在所有情况下都有效,例如如果您的映射值多于 ikeys 列中显示的值。
q)m:ikeys:1 2 3 5 7 11
q)ivals:100 100.5 101.5 99.5 100 100
q)update toupd: ivals from tab where ikeys in m
'length
点修正是另一种更容易推广到多个列的方法。它还可以利用就地修改,这将是内存效率最高的方法,因为它不会在内存中创建 table 的副本(假设为全局)。
ikeys:1 2 3 5
ivals:100 100.5 101.5 99.5
tab:([ikeys:1+til 7]toupd:.5 100.5 500.5 400.5 400.5 600.5 700.5;noupd:1 2 4 8 16 32 64)
q).[tab;(([]ikeys);`toupd);:;ivals]
ikeys| toupd noupd
-----| -----------
1 | 100 1
2 | 100.5 2
3 | 101.5 4
4 | 400.5 8
5 | 99.5 16
6 | 600.5 32
7 | 700.5 64
/amend in place
.[`tab;(([]ikeys);`toupd);:;ivals]
/generalise to two columns
q).[tab;(([]ikeys);`toupd`noupd);:;flip(ivals;1000 2000 3000 4000)]
ikeys| toupd noupd
-----| -----------
1 | 100 1000
2 | 100.5 2000
3 | 101.5 3000
4 | 400.5 8
5 | 99.5 4000
6 | 600.5 32
7 | 700.5 64
/you could amend in place here too
.[`tab;(([]ikeys);`toupd`noupd);:;flip(ivals;1000 2000 3000 4000)]
给定一个 ids/keys 列表和一组常量列的相应值:
q)ikeys: 1 2 3 5;
q)ivals: 100 100.5 101.5 99.5;
更新以下 table 中的 `toupd 列的最快方法是什么,以便将与给定 ikeys 匹配的行更新为 ivals:i.e.[= 中的新值13=]
q) show tab;
ikeys | `toupd `noupd
------|--------------
1 | 0.5 1
2 | 100.5 2
3 | 500.5 4
4 | 400.5 8
5 | 400.5 16
6 | 600.5 32
7 | 700.5 64
更新为:
q) show restab;
ikeys | `toupd `noupd
------|--------------
1 | 100 1
2 | 100.5 2
3 | 101.5 4
4 | 400.5 8
5 | 99.5 16
6 | 600.5 32
7 | 700.5 64
此外,是否有一种规范的方法可以以这种方式更新多个列。
谢谢
这里有两种不同的方法。
tab lj ([ikeys] toupd: ivals)
或
m: ikeys
update toupd: ivals from tab where ikeys in m
我相信还有很多方法。如果您想找出最适合您的目的(和您的数据)的方法,请尝试对大型表使用 q)\t:1000 yourCodeHere
并查看最适合您的方法。
至于哪个是多列的规范方式,我想应该是更新,但这是个人喜好问题,最快的就可以了。
字典也是给定映射更新值的常用方法。使用 ikeys 列索引字典给出新值,然后我们用旧的 toupd 列值填充空值。
q)show d:ikeys!ivals
1| 100
2| 100.5
3| 101.5
5| 99.5
q)update toupd:toupd^d ikeys from tab
ikeys| toupd noupd
-----| -----------
1 | 100 1
2 | 100.5 2
3 | 101.5 4
4 | 400.5 8
5 | 99.5 16
6 | 600.5 32
7 | 700.5 64
还值得注意的是,where 子句的更新条件并不能保证在所有情况下都有效,例如如果您的映射值多于 ikeys 列中显示的值。
q)m:ikeys:1 2 3 5 7 11
q)ivals:100 100.5 101.5 99.5 100 100
q)update toupd: ivals from tab where ikeys in m
'length
点修正是另一种更容易推广到多个列的方法。它还可以利用就地修改,这将是内存效率最高的方法,因为它不会在内存中创建 table 的副本(假设为全局)。
ikeys:1 2 3 5
ivals:100 100.5 101.5 99.5
tab:([ikeys:1+til 7]toupd:.5 100.5 500.5 400.5 400.5 600.5 700.5;noupd:1 2 4 8 16 32 64)
q).[tab;(([]ikeys);`toupd);:;ivals]
ikeys| toupd noupd
-----| -----------
1 | 100 1
2 | 100.5 2
3 | 101.5 4
4 | 400.5 8
5 | 99.5 16
6 | 600.5 32
7 | 700.5 64
/amend in place
.[`tab;(([]ikeys);`toupd);:;ivals]
/generalise to two columns
q).[tab;(([]ikeys);`toupd`noupd);:;flip(ivals;1000 2000 3000 4000)]
ikeys| toupd noupd
-----| -----------
1 | 100 1000
2 | 100.5 2000
3 | 101.5 3000
4 | 400.5 8
5 | 99.5 4000
6 | 600.5 32
7 | 700.5 64
/you could amend in place here too
.[`tab;(([]ikeys);`toupd`noupd);:;flip(ivals;1000 2000 3000 4000)]