多次元配列から列をどのように抽出しますか?


回答:


227
>>> import numpy as np
>>> A = np.array([[1,2,3,4],[5,6,7,8]])

>>> A
array([[1, 2, 3, 4],
    [5, 6, 7, 8]])

>>> A[:,2] # returns the third columm
array([3, 7])

参照:「numpy.arange」と「reshape」でメモリを割り当てる

例:(行列(3x4)の形状を持つ配列の割り当て)

nrows = 3
ncols = 4
my_array = numpy.arange(nrows*ncols, dtype='double')
my_array = my_array.reshape(nrows, ncols)

8
[:、2]を発見するのに2時間かかった[:、2]この機能は、スライスに関する公式の文献にはないと思いますか?
niken

コンマはどういう意味ですか?
Phil

3
@Phil [row, col]。コンマで区切ります。
AsheKetchum

11
この回答にはどのようにして多くの賛成票があるのでしょうか。OPは、それが
派手な

3
2列の抽出:A [:、[1,3]]たとえば、2列目と4列目の抽出
sadalsuud

176

NumPy配列を使用している可能性がありますか?Pythonには配列モジュールがありますが、多次元配列はサポートされていません。通常のPythonリストも1次元です。

ただし、次のような単純な2次元リストがある場合:

A = [[1,2,3,4],
     [5,6,7,8]]

次に、次のように列を抽出できます。

def column(matrix, i):
    return [row[i] for row in matrix]

2番目の列(インデックス1)の抽出:

>>> column(A, 1)
[2, 6]

または、単に:

>>> [row[1] for row in A]
[2, 6]

80

次のような配列がある場合

a = [[1, 2], [2, 3], [3, 4]]

次に、最初の列を次のように抽出します。

[row[0] for row in a]

したがって、結果は次のようになります。

[1, 2, 3]

38

見てみな!

a = [[1, 2], [2, 3], [3, 4]]
a2 = zip(*a)
a2[0]

これは上記と同じですが、zipが機能するのはきれいですが、引数として単一配列が必要です。* a構文は、多次元配列を単一配列引数にアンパックします。


7
上記は何ですか?回答が常に同じ方法で並べ替えられるとは限らないことに注意してください。
Muhd

2
これはクリーンですが、マトリックス全体を転置するため、パフォーマンスが問題になる場合は、最も効率的ではない可能性があります。
IceArdor、2014年

6
参考までに、これはpython 2で機能しますが、python 3ではジェネレーターオブジェクトを取得しますが、これはもちろん下付きではありません。
Rishabh Agrahari 16

@RishabhAgrahariとにかくPy3でこのzipを行うには?
CtrlAltF2

2
@WarpDriveEnterprisesそうです、ジェネレーターオブジェクトをリストに変換してから、添え字を付ける必要があります。例:a2 = zip(*a); a2 = list(a2); a2[0]
Rishabh Agrahari

14
def get_col(arr, col):
    return map(lambda x : x[col], arr)

a = [[1,2,3,4], [5,6,7,8], [9,10,11,12],[13,14,15,16]]

print get_col(a, 3)

Pythonのマップ関数は別の方法です。


11
>>> x = arange(20).reshape(4,5)
>>> x array([[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19]])

2列目が必要な場合は使用できます

>>> x[:, 1]
array([ 1,  6, 11, 16])

1
これはnumpyを使用していますか?
Foreever

1
arange()numpy以外のPython3のドキュメントは見つかりません。誰でも?
ケビンWマシューズ


9

リストの内包表記ではなく、map-reduceスタイルのpythonが少し好きな場合は、itemgetter演算子も役立ちます。

# tested in 2.4
from operator import itemgetter
def column(matrix,i):
    f = itemgetter(i)
    return map(f,matrix)

M = [range(x,x+5) for x in range(10)]
assert column(M,1) == range(1,11)

1
大規模データのためitertools.imapを使用
パヴェルPolewicz

itemgetterアプローチは、私のユースケースのリスト内包アプローチよりも約50倍速く実行されました。Python 2.7.2のユースケースは、数百の行と列を持つマトリックスでの多くの反復でした。
joelpt 2012年

7

これも使用できます。

values = np.array([[1,2,3],[4,5,6]])
values[...,0] # first column
#[1,4]

注:これは組み込み配列では機能せず、位置合わせされません(例:np.array([[1,2,3]、[4,5,6,7]]))


6

以下の配列のような配列から列を抽出したいと思います

import numpy as np
A = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])

次に、フォーマットの3番目の列を取得する場合

D=array[[3],
[7],
[11]]

次に、最初に配列を行列にする必要があります

B=np.asmatrix(A)
C=B[:,2]
D=asarray(C)

そして今、あなたはExcelと同じように要素ごとの計算をすることができます。


1
これは私に大いに役立ちましたが、答えはもっと短くなると思います:1. A = np.array([[1,2,3,4]、[5,6,7,8]、[9,10、 11,12]])2. A [:, 1] >> array([
2、6、10

6

n X mマトリックス(n行とm列)が5行と4列を持っているとしましょう

matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19,20]]

Pythonで列を抽出するには、次のようなリスト内包表記を使用できます。

[ [row[i] for row in matrix] for in range(4) ]

4は、マトリックスの列数に置き換えることができます。結果は

[ [1,5,9,13,17],[2,10,14,18],[3,7,11,15,19],[4,8,12,16,20] ]


これは完全に新しいリストを作成しますか?
ケビンWマシューズ

5
array = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]

col1 = [val[1] for val in array]
col2 = [val[2] for val in array]
col3 = [val[3] for val in array]
col4 = [val[4] for val in array]
print(col1)
print(col2)
print(col3)
print(col4)

Output:
[1, 5, 9, 13]
[2, 6, 10, 14]
[3, 7, 11, 15]
[4, 8, 12, 16]

4

行列を使用するもう1つの方法

>>> from numpy import matrix
>>> a = [ [1,2,3],[4,5,6],[7,8,9] ]
>>> matrix(a).transpose()[1].getA()[0]
array([2, 5, 8])
>>> matrix(a).transpose()[0].getA()[0]
array([1, 4, 7])

3

Python(numpyではない)に2次元配列がある場合は、そのようにすべての列を抽出できます。

data = [
['a', 1, 2], 
['b', 3, 4], 
['c', 5, 6]
]

columns = list(zip(*data))

print("column[0] = {}".format(columns[0]))
print("column[1] = {}".format(columns[1]))
print("column[2] = {}".format(columns[2]))

このコードを実行すると、

>>> print("column[0] = {}".format(columns[0]))
column[0] = ('a', 'b', 'c')

>>> print("column[1] = {}".format(columns[1]))
column[1] = (1, 3, 5)

>>> print("column[2] = {}".format(columns[2]))
column[2] = (2, 4, 6)

もちろん、あなたがインデックスによって単一の列を抽出することができます(例えばcolumns[0]


2

使用したにも関わらずzip(*iterable)、ネストされたリストを移調するネストされたリストは、長さが異なる場合、あなたはまた、次のように使用することができます。

map(None, *[(1,2,3,), (4,5,), (6,)])

結果は:

[(1, 4, 6), (2, 5, None), (3, None, None)]

したがって、最初の列は次のとおりです。

map(None, *[(1,2,3,), (4,5,), (6,)])[0]
#>(1, 4, 6)

2

まあ「ビット」遅れ...

パフォーマンスが重要でデータが長方形の場合は、1次元でデータを保存し、通常のスライスで列にアクセスすることもできます...

A = [[1,2,3,4],[5,6,7,8]]     #< assume this 4x2-matrix
B = reduce( operator.add, A ) #< get it one-dimensional

def column1d( matrix, dimX, colIdx ):
  return matrix[colIdx::dimX]

def row1d( matrix, dimX, rowIdx ):
  return matrix[rowIdx:rowIdx+dimX] 

>>> column1d( B, 4, 1 )
[2, 6]
>>> row1d( B, 4, 1 )
[2, 3, 4, 5]

すごいのは、これが本当に速いということです。ただし、負のインデックスはここでは機能しません!したがって、インデックス-1で最後の列または行にアクセスすることはできません。

負のインデックスが必要な場合は、アクセサ関数を少し調整できます。たとえば、

def column1d( matrix, dimX, colIdx ):
  return matrix[colIdx % dimX::dimX]

def row1d( matrix, dimX, dimY, rowIdx ):
  rowIdx = (rowIdx % dimY) * dimX
  return matrix[rowIdx:rowIdx+dimX]

この方法を確認したところ、列を取得するコストはネストされたforループよりもはるかに安価です。ただし、行列が大きい場合、つまり1000 * 1000の場合、2d行列を1dに削減するにはコストがかかります。
Zhongjun 'Mark' Jin

2

複数の列だけを取得したい場合は、sliceを使用します。

 a = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
    print(a[:, [1, 2]])
[[2 3]
[5 6]
[8 9]]

2

私は次のヒントを好みます:マトリックスに名前を付けmatrix_aて使用するcolumn_number、例えば:

import numpy as np
matrix_a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
column_number=2

# you can get the row from transposed matrix - it will be a column:
col=matrix_a.transpose()[column_number]

1

transpose()を使用するだけで、列を取得するのと同じくらい簡単に列を取得できます

matrix=np.array(originalMatrix).transpose()
print matrix[NumberOfColum]

0

行列からすべての列を新しいリストに:

N = len(matrix) 
column_list = [ [matrix[row][column] for row in range(N)] for column in range(N) ]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.