Python NumPy 列表理解语法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21360028/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
NumPy List Comprehension Syntax
提问by Andrew Latham
I'd like to be able to use list comprehension syntax to work with NumPy arrays easily.
我希望能够使用列表理解语法轻松处理 NumPy 数组。
For instance, I would like something like the below obviously wrong code to just reproduce the same array.
例如,我想要类似下面明显错误的代码来重现相同的数组。
>>> X = np.random.randn(8,4)
>>> [[X[i,j] for i in X] for j in X[i]]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: arrays used as indices must be of integer (or boolean) type
What is the easy way to do this, to avoid using range(len(X)?
有什么简单的方法可以做到这一点,以避免使用range(len(X)?
回答by falsetru
Do you mean following?
你的意思是跟随?
>>> [[X[i,j] for j in range(X.shape[1])] for i in range(X.shape[0])]
[[0.62757350000000001, -0.64486080999999995, -0.18372566000000001, 0.78470704000000002],
[1.78209799, -1.336448459999999 9, -1.3851422200000001, -0.49668994],
[-0.84148266000000005, 0.18864597999999999, -1.1135151299999999, -0.40225053999999 999],
[0.93852824999999995, 0.24652238000000001, 1.1481637499999999, -0.70346624999999996],
[0.83842508000000004, 1.0058 697599999999, -0.91267403000000002, 0.97991269000000003],
[-1.4265273000000001, -0.73465904999999998, 0.6684284999999999 8, -0.21551155],
[-1.1115614599999999, -1.0035033200000001, -0.11558254, -0.4339924],
[1.8771354, -1.0189299199999999, - 0.84754008000000003, -0.35387946999999997]]
Using numpy.ndarray.copy:
>>> X.copy()
array([[ 0.6275735 , -0.64486081, -0.18372566, 0.78470704],
[ 1.78209799, -1.33644846, -1.38514222, -0.49668994],
[-0.84148266, 0.18864598, -1.11351513, -0.40225054],
[ 0.93852825, 0.24652238, 1.14816375, -0.70346625],
[ 0.83842508, 1.00586976, -0.91267403, 0.97991269],
[-1.4265273 , -0.73465905, 0.6684285 , -0.21551155],
[-1.11156146, -1.00350332, -0.11558254, -0.4339924 ],
[ 1.8771354 , -1.01892992, -0.84754008, -0.35387947]])
回答by abarnert
First, you should not be using NumPy arrays as lists of lists.
首先,您不应将 NumPy 数组用作列表列表。
Second, let's forget about NumPy; your listcomp doesn't make any sense in the first place, even for lists of lists.
其次,让我们忘记 NumPy;您的 listcomp 一开始就没有任何意义,即使对于列表列表也是如此。
In the inner comprehension, for i in Xis going to iterate over the rows in X. Those rows aren't numbers, they're lists (or, in NumPy, 1D arrays), so X[i]makes no sense whatsoever. You may have wanted i[j]instead.
在内部理解中,for i in X将迭代 X 中的行。这些行不是数字,它们是列表(或者,在 NumPy 中,一维数组),因此X[i]没有任何意义。你可能想要i[j]。
In the outer comprehension, for j in X[i]has the same problem, but is has an even bigger problem: there is no ivalue. You have a comprehension looping over each iinsidethis comprehension.
在外在理解上,for j in X[i]有同样的问题,但有一个更大的问题:没有i价值。你有一个理解i在这个理解中循环。
If you're confused by a comprehension, write it out as an explicit forstatement, as explained in the tutorial section on List Comprehensions:
如果您对推导式感到困惑,请将其写成一个明确的for陈述,如列表推导式的教程部分所述:
tmp = []
for j in X[i]:
tmp.append([X[i,j] for i in X])
… which expands to:
… 扩展为:
tmp = []
for j in X[i]:
tmp2 = []
for i in X:
tmp2.append(X[i,j])
tmp.append(tmp2)
… which should make it obvious what's wrong here.
......这应该很明显这里出了什么问题。
I think what you wanted was:
我想你想要的是:
[[cell for cell in row] for row in X]
Again, turn it back into explicit forstatements:
再次将其转回显式for语句:
tmp = []
for row in X;
tmp2 = []
for cell in row:
tmp2.append(cell)
tmp.append(tmp2)
That's obviously right.
这显然是对的。
Or, if you really want to use indexing (but you don't):
或者,如果你真的想使用索引(但你没有):
[[X[i][j] for j in range(len(X[i]))] for i in range(len(X))]
So, back to NumPy. In NumPy terms, that last version is:
所以,回到 NumPy。用 NumPy 术语来说,最后一个版本是:
[[X[i,j] for j in range(X.shape[1])] for i in range(X.shape[0])]
… and if you want to go in column-major order instead of row-major, you can (unlike with a list of lists):
...如果你想按列优先顺序而不是行优先顺序,你可以(与列表列表不同):
[[X[i,j] for i in range(X.shape[0])] for j in range(X.shape[1])]
… but that will of course transpose the array, which isn't what you wanted to do.
……但这当然会转置数组,这不是您想要做的。
The one thing you can'tdo is mix up column-major and row-major order in the same expression, because you end up with nonsense.
你不能做的一件事是在同一个表达式中混合列优先顺序和行优先顺序,因为你最终会胡说八道。
Of course the rightway to make a copy of an array is to use the copymethod:
当然,复制数组的正确方法是使用以下copy方法:
X.copy()
Just as the right way to transpose an array is:
正如转置数组的正确方法是:
X.T
回答by user2357112 supports Monica
The easy way is to not do this. Use numpy's implicit vectorization instead. For example, if you have arrays A and B as follows:
简单的方法是不要这样做。改用 numpy 的隐式矢量化。例如,如果您有数组 A 和 B,如下所示:
A = numpy.array([[1, 3, 5],
[2, 4, 6],
[9, 8, 7]])
B = numpy.array([[5, 3, 5],
[3, 5, 3],
[5, 3, 5]])
then the following code using list comprehensions:
然后使用列表理解的以下代码:
C = numpy.array([[A[i, j] * B[i, j] for j in xrange(A.shape[1])]
for i in xrange(A.shape[0])])
can be much more easily written as
可以更容易地写成
C = A * B
It'll also run much faster. Generally, you will produce faster, clearer code if you don't use list comprehensions with numpy than if you do.
它也会运行得更快。通常,如果您不使用 numpy 的列表推导式,您将生成更快、更清晰的代码。
If you really want to use list comprehensions, standard Python list-comprehension-writing techniques apply. Iterate over the elements, not the indices:
如果您真的想使用列表推导式,则适用标准的 Python 列表推导式编写技术。迭代元素,而不是索引:
C = numpy.array([[a*b for a, b in zip(a_row, b_row)]
for a_row, b_row in zip(A, B)]
Thus, your example code would become
因此,您的示例代码将变为
numpy.array([[elem for elem in x_row] for x_row in X])
回答by exogeographer
Another option (though not necessarily performant) is to rethink your problem as a map instead of a comprehension and write a ufunc:
另一种选择(虽然不一定高效)是将您的问题重新考虑为地图而不是理解并编写一个 ufunc:
http://docs.scipy.org/doc/numpy/reference/ufuncs.html
http://docs.scipy.org/doc/numpy/reference/ufuncs.html
You can call functional-lite routines like:
您可以调用功能精简例程,例如:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.apply_over_axes.htmlhttp://docs.scipy.org/doc/numpy/reference/generated/numpy.vectorize.html
http://docs.scipy.org/doc/numpy/reference/generated/numpy.apply_over_axes.html http://docs.scipy.org/doc/numpy/reference/generated/numpy.vectorize.html
Etc.
等等。

