1

各配列の各列の最初の要素に基づいて、Pythonで2つの配列をマージしたいと思います。

例えば、

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

B = ([[1, .002],
[4, .005],
[5, .006]])

配列を取得するため

C = ([[1, 2, 3, .002],
[4, 5, 6, .005],
[4, 6, 7, .005],
[5, 7, 8, .006],
[5, 9, 1, .006]])

より明確にするために:

Aの最初の列は1、4、4、5、5で、Bの最初の列は1、4、5です。

したがって、Aの1はBの1と一致し、.002を取得します。

Pythonでこれを行うにはどうすればよいですか?どんな提案も素晴らしいでしょう。

4

5 に答える 5

1

その場で変更Aしてもよろしいですか?:

d = dict((x[0],x[1:]) for x in B)

これdは、最初の列がキーで、後続の列が値である辞書です。

for lst in A:
    if lst[0] in d: #Is the first value something that we can extend?
        lst.extend(d[lst[0]])

print A

それを場違いにするには(Ashwiniの回答に触発されました):

d = dict((x[0],x[1:]) for x in B)
C = [lst + d.get(lst[0],[]) for lst in A]

ただし、このアプローチでは、A と B の両方にリストが必要です。いくつかのリストといくつかのタプルがある場合は失敗します (必要に応じて回避できますが) が、コードが少し複雑になります。

これらの答えのいずれかでB、任意の数の列を持つことができます

スタイルに関する補足として、リストを次のように記述します。

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

括弧を削除したところ...リストを . に入れているように見えすぎますtuple。Python の自動行継続は、括弧()、角括弧[]、または中括弧で発生します{}

于 2013-01-10T21:51:47.917 に答える
0

(この回答は、これらが単なる通常のリストであることを前提としています。NumPy 配列の場合は、より多くのオプションがあります。)

B をルックアップ テーブルとして使用して、A の各行に追加する値を見つけたいようです。

B のデータから辞書を作成することから始めます。たまたま、B は既にdict()ビルトインに渡される適切な形式になっています。

B_dict = dict(B)

次に、行ごとに C をビルドするだけです。

A の各行row[0]の最初の要素はB_dict[row[0]]、行の最後に追加する値です。したがってrow + [B_dict[row[0]]、C に追加する行です。

以下は、A と B_dict から C を構築するリスト内包表記です。

C = [row + [B_dict[row[0]]] for row in A]
于 2013-01-10T21:47:50.260 に答える
0

B各サブリストの最初の要素をキーとして、2 番目の要素を値として、dictionary最初の要素に変換できます。

A次に、辞書から取得した関連する値を繰り返して追加します。

In [114]: A = ([1, 2, 3],
[4, 5, 6],
[4, 6, 7],
[5, 7, 8], 
[6, 9, 1])

In [115]: B = ([1, .002],
[4, .005],
[5, .006])

In [116]: [x + [dic[x[0]]] if x[0] in dic else []  for x in A]
Out[116]: 
[[1, 2, 3, 0.002],
 [4, 5, 6, 0.005],
 [4, 6, 7, 0.005],
 [5, 7, 8, 0.006],
 [6, 9, 1]]
于 2013-01-10T21:53:19.970 に答える
0

素朴で簡単な方法:

for alist in A:
    for blist in B:
        if blist[0] == alist[0]:
            alist.extend(blist[1:])
            # alist.append(blist[1]) if B will only ever contain 2-tuples.
            break  # Remove this if you want to append more than one.

ここでの欠点は、O(N^2) の複雑さです。ほとんどの小さなデータ セットでは、これで問題ありません。より包括的なものを探している場合は、おそらく @mgilson の回答を見たいと思うでしょう。いくつかの比較:

  1. 彼の応答は、すべてをBdict に変換し、各要素に対してリスト スライスを実行します。に多くの値がある場合、Bコストが高くなる可能性があります。これは既存のリストを使用します (とにかく、最初の値だけを見ています)。
  2. 彼はディクテーションを使用しているため、O(1) ルックアップ時間を取得します (彼の答えは、 の値の末尾に複数の値を追加しないことも前提としていますA)。つまり、全体として、彼のアルゴリズムは O(N) を達成します。dict を作成するオーバーヘッドが の値の反復を上回るかどうかを検討する必要がありますB
于 2013-01-11T02:04:42.483 に答える
0

itertools.product()B のディクショナリを作成する必要がないようにするソリューションを次に示します。

In [1]: from itertools import product

In [2]: [lst_a + lst_b[1:] for (lst_a, lst_b) in product(A, B) if lst_a[0] == lst_b[0]]
Out[2]:
[[1, 2, 3, 0.002],
 [4, 5, 6, 0.005],
 [4, 6, 7, 0.005],
 [5, 7, 8, 0.006],
 [5, 9, 1, 0.006]]
于 2013-01-11T01:45:31.970 に答える