web-dev-qa-db-ja.com

データフレーム内の列のすべての可能な組み合わせ-pandas / python

1つのデータフレームを取得して別のデータフレームを作成しようとしています。列のすべての可能な組み合わせと、対応する値の差があります。つまり、11-apr列ABでは(B-A)= 0などになります。

例:

        Dt              A           B           C          D
        11-apr          1           1           1          1
        10-apr          2           3           1          2

次のような新しいフレームを取得するにはどうすればよいですか。

desired result

以下の投稿に出くわしましたが、これを列に置き換えることができませんでした。

パンダを使用してすべてのデータフレーム行ペアの組み合わせを集計します

5
S.Peters

次を使用できます。

from itertools import combinations
df = df.set_index('Dt')

cc = list(combinations(df.columns,2))
df = pd.concat([df[c[1]].sub(df[c[0]]) for c in cc], axis=1, keys=cc)
df.columns = df.columns.map(''.join)
print (df)
        AB  AC  AD  BC  BD  CD
Dt                            
11-apr   0   0   0   0   0   0
10-apr   1  -1   0  -2  -1   1
9
jezrael

インデックスがDtであることを確認してください

df = df.set_index('Dt')

numpys np.tril_indicesの使用とスライスnp.triu_indicesの説明については、以下を参照してください。

v = df.values

i, j = np.tril_indices(len(df.columns), -1)

列にpd.MultiIndexを作成できます。これにより、1文字より長い列名に対してより一般化できるようになります。

pd.DataFrame(
    v[:, i] - v[:, j],
    df.index,
    [df.columns[j], df.columns[i]]
)

        A     B  A  B  C
        B  C  C  D  D  D
Dt                      
11-apr  0  0  0  0  0  0
10-apr  1 -1 -2  0 -1  1

しかし、私たちもできます

pd.DataFrame(
    v[:, i] - v[:, j],
    df.index,
    df.columns[j] + df.columns[i]
)

        AB  AC  BC  AD  BD  CD
Dt                            
11-apr   0   0   0   0   0   0
10-apr   1  -1  -2   0  -1   1

np.tril_indices説明

これはnumpy関数であり、一緒に使用すると、正方行列の下三角形の位置を提供する2つの配列を返します。この下の三角形は、行列の1つの軸と他の軸のすべての組み合わせを表すため、これは、すべての組み合わせを操作するときに便利です。

説明のためにデータフレームdを検討してください

d = pd.DataFrame(np.array(list('abcdefghijklmnopqrstuvwxy')).reshape(-1, 5))
d

   0  1  2  3  4
0  a  b  c  d  e
1  f  g  h  i  j
2  k  l  m  n  o
3  p  q  r  s  t
4  u  v  w  x  y

三角形のインデックスは、座標ペアのように見ると、次のようになります。

i, j = np.tril_indices(5, -1)
list(Zip(i, j))

[(1, 0),
 (2, 0),
 (2, 1),
 (3, 0),
 (3, 1),
 (3, 2),
 (4, 0),
 (4, 1),
 (4, 2),
 (4, 3)]

diを使用してjsの値を操作できます

d.values[i, j] = 'z'
d

   0  1  2  3  4
0  a  b  c  d  e
1  z  g  h  i  j
2  z  z  m  n  o
3  z  z  z  s  t
4  z  z  z  z  y

そして、あなたはそれがちょうどその下の三角形をターゲットにしているのを見ることができます

ナイーブタイムテスト

enter image description here

5
piRSquared

itertools.combinations が手伝う:

import itertools
pd.DataFrame({'{}{}'.format(a, b): df[a] - df[b] for a, b in itertools.combinations(df.columns, 2)})

その結果:

        AB  AC  AD  BC  BD  CD
Dt                            
11-apr   0   0   0   0   0   0
10-apr  -1   1   0   2   1  -1
1
languitar

Itertoolsモジュールは、必要な組み合わせ/順列を作成するのに役立ちます。

from itertools import combinations

# Creating a new pd.DataFrame
new_df = pd.DataFrame(index=df.index)

# list of columns
columns = df.columns

# Create all combinations of length 2 . eg. AB, BC, etc.
for combination in combinations(columns, 2):
    combination_string = "".join(combination)
    new_df[combination_string] = df[combination[1]]-df[combination[0]]
    print new_df


         AB  AC  AD  BC  BD  CD
Dt                            
11-apr   0   0   0   0   0   0
10-apr   1  -1   0  -2  -1   1
0
Nipun Batra