如何更改由元组组成的矩阵中的列?
How to change a column in a matrix made of tuples?
我不确定将元组矩阵转换为更易于操作的列表形式的成本。主要优先事项是能够将矩阵的列更改为 fast 尽可能
我有一个形式为
的矩阵
[(a,b,c),(d,e,f),(g,h,i)]
它可以以 n x m 的任何大小出现,但对于此示例,我们将采用 3x3 矩阵。
我的主要目标是能够更改矩阵中任何列的值(一次只能更改一个)(例如 (b,e,h))。
我最初的尝试是将矩阵转换为列表即
[[a,b,c],[d,e,f],[g,h,i]]
哪个更容易
但我觉得将每个元组转换为列表再转换回元组的成本很高。
我的主要问题可能是如何最大限度地优化它?
In [37]: def change_column_list_comp(old_m, col, value):
...: return [
...: tuple(list(row[:col]) + [value] + list(row[col + 1:]))
...: for row in old_m
...: ]
...:
In [38]: def change_column_list_convert(old_m, col, value):
...: list_m = list(map(list, old_m))
...: for row in list_m:
...: row[col] = value
...:
...: return list(map(tuple, list_m))
...:
In [39]: m = [tuple('abc'), tuple('def'), tuple('ghi')]
In [40]: %timeit change_column_list_comp(m, 1, 2)
2.05 µs ± 89.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [41]: %timeit change_column_list_convert(m, 1, 2)
1.28 µs ± 121 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
看起来转换为 list
、修改值并转换回 tuple
的速度更快。请注意,这可能不是编写这些函数的最有效方式。
但是,随着我们扩大矩阵,这些函数似乎开始收敛。
In [6]: m_100k = [tuple(string.printable)] * 100_000
In [7]: %timeit change_column_list_comp(m_100k, 1, 2)
163 ms ± 3.7 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [8]: %timeit change_column_list_convert(m_100k, 1, 2)
117 ms ± 5.67 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [42]: m_1m = [tuple(string.printable)] * 1_000_000
In [43]: %timeit change_column_list_comp(m_1m, 1, 2)
1.72 s ± 74.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [44]: %timeit change_column_list_convert(m_1m, 1, 2)
1.24 s ± 84.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
归根结底,您应该使用正确的工具来完成工作。虽然它并不真正在 OP 中,但值得一提的是 numpy
只是更好的方法。
In [13]: m_np = np.array([list('abc'), list('def'), list('ghi')])
In [17]: %timeit m_np[:, 1] = 2; m_np
610 ns ± 48.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [20]: m_np_100k = np.array([[string.printable] * 100_000])
In [21]: %timeit m_np_100k[:, 1] = 2; m_np_100k
545 ns ± 63.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [22]: m_np_1m = np.array([[string.printable] * 1_000_000])
# This might be using cached data
In [23]: %timeit m_np_1m[:, 1] = 2; m_np_1m
515 ns ± 31.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
# Avoiding cache
In [24]: %timeit m_np_1m[:, 4] = 9; m_np_1m
557 ns ± 37.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
这可能不是最公平的比较,因为我们手动返回矩阵,但您可以看到有显着改进。
我不确定将元组矩阵转换为更易于操作的列表形式的成本。主要优先事项是能够将矩阵的列更改为 fast 尽可能
我有一个形式为
的矩阵[(a,b,c),(d,e,f),(g,h,i)]
它可以以 n x m 的任何大小出现,但对于此示例,我们将采用 3x3 矩阵。 我的主要目标是能够更改矩阵中任何列的值(一次只能更改一个)(例如 (b,e,h))。
我最初的尝试是将矩阵转换为列表即
[[a,b,c],[d,e,f],[g,h,i]]
哪个更容易
但我觉得将每个元组转换为列表再转换回元组的成本很高。
我的主要问题可能是如何最大限度地优化它?
In [37]: def change_column_list_comp(old_m, col, value):
...: return [
...: tuple(list(row[:col]) + [value] + list(row[col + 1:]))
...: for row in old_m
...: ]
...:
In [38]: def change_column_list_convert(old_m, col, value):
...: list_m = list(map(list, old_m))
...: for row in list_m:
...: row[col] = value
...:
...: return list(map(tuple, list_m))
...:
In [39]: m = [tuple('abc'), tuple('def'), tuple('ghi')]
In [40]: %timeit change_column_list_comp(m, 1, 2)
2.05 µs ± 89.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [41]: %timeit change_column_list_convert(m, 1, 2)
1.28 µs ± 121 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
看起来转换为 list
、修改值并转换回 tuple
的速度更快。请注意,这可能不是编写这些函数的最有效方式。
但是,随着我们扩大矩阵,这些函数似乎开始收敛。
In [6]: m_100k = [tuple(string.printable)] * 100_000
In [7]: %timeit change_column_list_comp(m_100k, 1, 2)
163 ms ± 3.7 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [8]: %timeit change_column_list_convert(m_100k, 1, 2)
117 ms ± 5.67 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [42]: m_1m = [tuple(string.printable)] * 1_000_000
In [43]: %timeit change_column_list_comp(m_1m, 1, 2)
1.72 s ± 74.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [44]: %timeit change_column_list_convert(m_1m, 1, 2)
1.24 s ± 84.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
归根结底,您应该使用正确的工具来完成工作。虽然它并不真正在 OP 中,但值得一提的是 numpy
只是更好的方法。
In [13]: m_np = np.array([list('abc'), list('def'), list('ghi')])
In [17]: %timeit m_np[:, 1] = 2; m_np
610 ns ± 48.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [20]: m_np_100k = np.array([[string.printable] * 100_000])
In [21]: %timeit m_np_100k[:, 1] = 2; m_np_100k
545 ns ± 63.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [22]: m_np_1m = np.array([[string.printable] * 1_000_000])
# This might be using cached data
In [23]: %timeit m_np_1m[:, 1] = 2; m_np_1m
515 ns ± 31.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
# Avoiding cache
In [24]: %timeit m_np_1m[:, 4] = 9; m_np_1m
557 ns ± 37.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
这可能不是最公平的比较,因为我们手动返回矩阵,但您可以看到有显着改进。