2

次のような 2 つの pandas データ フレームがあります。

import pandas as pd

df_one = pd.DataFrame( {
    'A': [1,1,2,3,4,4,4],
    'B1': [0.5,0.0,0.2,0.1,0.3,0.2,0.1],
    'B2': [0.2,0.3,0.1,0.5,0.3,0.1,0.2],
    'B3': [0.1,0.2,0.0,0.9,0.0,0.3,0.5]} );
df_two = pd.DataFrame( {
    'A': [1,2,3,4],
    'C1': [1.0,9.0,2.1,9.0],
    'C2': [2.0,3.0,0.7,1.1],
    'C3': [5.0,4.0,2.3,3.4]} );

df_one
   A   B1   B2   B3
0  1  0.5  0.2  0.1
1  1  0.0  0.3  0.2
2  2  0.2  0.1  0.0
3  3  0.1  0.5  0.9
4  4  0.3  0.3  0.0
5  4  0.2  0.1  0.3
6  4  0.1  0.2  0.5

df_two
   A   C1   C2   C3
0  1  1.0  2.0  5.0
1  2  9.0  3.0  4.0
2  3  2.1  0.7  2.3
3  4  9.0  1.1  3.4

私がやりたいのは、最初のデータ フレームの行を 2 番目のデータ フレームの行で乗算するスカラー積を計算することです。つまり、\sum_i B_i * C_i最初のデータ フレームの行が乗算されるようにします。列の値がA両方のフレームで一致する場合にのみ、2 番目のデータ フレームの行によって。ループしてifを使用する方法は知っていますが、より効率的なnumpyのような方法またはパンダのような方法でそれを行いたいと思います。どんな助けでも大歓迎です:)

4

3 に答える 3

1

列 A に一意の値が必要かどうかわからない (必要な場合は、以下の結果で groupby を使用してください)

pd.merge(df_one, df_two, on='A')
   A   B1   B2   B3   C1   C2   C3
0  1  0.5  0.2  0.1  1.0  2.0  5.0
1  1  0.0  0.3  0.2  1.0  2.0  5.0
2  2  0.2  0.1  0.0  9.0  3.0  4.0
3  3  0.1  0.5  0.9  2.1  0.7  2.3
4  4  0.3  0.3  0.0  9.0  1.1  3.4
5  4  0.2  0.1  0.3  9.0  1.1  3.4
6  4  0.1  0.2  0.5  9.0  1.1  3.4

    pd.merge(df_one, df_two, on='A').apply(lambda s: sum([s['B%d'%i] * s['C%d'%i] for i in range(1, 4)]) , axis=1)
0    1.40
1    1.60
2    2.10
3    2.63
4    3.03
5    2.93
6    2.82
于 2013-07-15T19:35:11.023 に答える
1

別のアプローチは、次のようなものです。

import pandas as pd

df_one = pd.DataFrame( {
    'A': [1,1,2,3,4,4,4],
    'B1': [0.5,0.0,0.2,0.1,0.3,0.2,0.1],
    'B2': [0.2,0.3,0.1,0.5,0.3,0.1,0.2],
    'B3': [0.1,0.2,0.0,0.9,0.0,0.3,0.5]} );
df_two = pd.DataFrame( {
    'A': [1,2,3,4],
    'C1': [1.0,9.0,2.1,9.0],
    'C2': [2.0,3.0,0.7,1.1],
    'C3': [5.0,4.0,2.3,3.4]} );
lookup = df_two.groupby(df_two.A)

def multiply_rows(row):
    other = lookup.get_group(row['A'])
    # We want every column after "A"
    x = row.values[1:]
    # In this case, other is a 2D array with one row, similar to "row" above...
    y = other.values[0, 1:]
    return x.dot(y)

# The "axis=1" makes each row to be passed in, rather than each column
result = df_one.apply(multiply_rows, axis=1)
print result

これにより、次の結果が得られます。

0    1.40
1    1.60
2    2.10
3    2.63
4    3.03
5    2.93
6    2.82
于 2013-07-15T21:49:49.223 に答える