2

私は非常に大きな DataFrame を持っており、いくつかの重いグループごとの比較を行いたいと考えています。例として、次のサンプルを見てみましょう。

df = pd.DataFrame({'A': ['foo', 'bar'] * 3,
               'B': ['me', 'you', 'me'] * 2,
               'C': [5, 2, 3, 4, 6, 9]})

ここで、列 A でグループ化し、これらのグループを効率的にループして、次の方法で行単位の比較を行いたいと思います。

gb = df.groupby(['A'])

for k, gp in gb:
    for i in arange(len(gp['C'])):
        sum = 0
        for j in arange(len(gp['C'])):
            if (i != j):
                sum = sum + gp['C'].irow(j)
        print gp['C'].irow(i) - sum

この操作をより効率的に行い、その結果をデータフレームの別の列に割り当てる可能性はありますか?

私はあなたの助けに深く感謝します

アンディ

4

1 に答える 1

3

私には少し奇妙に思えますが、IIUC、あなたの出力は

df["weird_C"] = 2*df["C"] - df.groupby("A")["C"].transform(np.sum)

例えば:

>>> df = pd.DataFrame({'A': ['foo', 'bar'] * 3,
               'B': ['me', 'you', 'me'] * 2,
               'C': [5, 2, 3, 4, 6, 9]})
>>> df
     A    B  C
0  foo   me  5
1  bar  you  2
2  foo   me  3
3  bar   me  4
4  foo  you  6
5  bar   me  9
>>> df["weird_C"] = 2*df["C"] - df.groupby("A")["C"].transform(np.sum)
>>> df
     A    B  C  weird_C
0  foo   me  5       -4
1  bar  you  2      -11
2  foo   me  3       -8
3  bar   me  4       -7
4  foo  you  6       -2
5  bar   me  9        3

基本的に、pandas高速なベクトル化された C では、一度にできることが多いほど、物事はうまく機能します。この場合、グループ メンバーをループするのではなく、一度に合計を取得してから、追加した余分なビットを差し引くことができます。

>>> df.groupby("A")["C"].sum()
A
bar    15
foo    14
Name: C, dtype: int64

さらに良いことtransformに、ブロードキャストでグループ合計の Series が得られるように使用できます。

>>> df.groupby("A")["C"].transform(np.sum)
0    14
1    15
2    14
3    15
4    14
5    15
Name: C, dtype: int64

次に、グループの合計があり、各値と他の値の差が本当に必要なので、「x - 残り」を「x + x - x - 残り」または「x + x - (合計)」、または「2*x - 合計」:

>>> 2*df["C"] - df.groupby("A")["C"].transform(np.sum)
0    -4
1   -11
2    -8
3    -7
4    -2
5     3
Name: C, dtype: int64
于 2013-05-28T16:35:20.923 に答える