2016-08-12 9 views
4

DataFrameがあり、各列のすべての値をその列の合計に割り当てようとしています。各列の値をその列の合計に割り当てる

x = pd.DataFrame(data = [[1,2],[3,4],[5,6],[7,8],[9,10]],index=[1,2,3,4,5],columns=['a','b']) 
x 
    a b 
1 1 2 
2 3 4 
3 5 6 
4 7 8 
5 9 10 

出力は

a b 
1 25 30 
2 25 30 
3 25 30 
4 25 30 
5 25 30 

する必要があります私はx.apply(F、軸= 0)を使用したいが、私はあることを、列を変換する関数を定義する方法がわかりませんラムダ関数のすべての列値の合計。次の行のレイズにSyntaxError:私はあなたが何をしようとしている内容を正確に把握していない

f = lambda x : x[:]= x.sum() 
+1

あなたのデータフレームの小さなスニペットを共有してもらえますか? –

+1

"ラムダ関数を次のように定義することはできません":これは何と言うのですか? –

+1

'df.sum()'はあなたが望むことをやってくれませんか、あるいは本当に*合計ですべての列を上書きしたいのですか? (私はあなたがそれをしたいと思う理由を考えるのに苦労しています...) –

答えて

5

別速くnumpyのnumpy.tileと解決策:numpy.repeat

print (pd.DataFrame(np.tile(x.sum().values, (len(x.index),1)), 
        columns=x.columns, 
        index=x.index)) 
    a b 
1 25 30 
2 25 30 
3 25 30 
4 25 30 
5 25 30 

別の解決策:

transformを使用して
h = pd.DataFrame(x.sum().values[np.newaxis,:].repeat(len(x.index), axis=0), 
       columns=x.columns, 
       index=x.index) 

print (h) 
    a b 
1 25 30 
2 25 30 
3 25 30 
4 25 30 
5 25 30 


In [431]: %timeit df = pd.DataFrame([x.sum()] * len(x)) 
1000 loops, best of 3: 786 µs per loop 

In [432]: %timeit (pd.DataFrame(np.tile(x.sum().values, (len(x.index),1)), columns=x.columns, index=x.index)) 
1000 loops, best of 3: 192 µs per loop 

In [460]: %timeit pd.DataFrame(x.sum().values[np.newaxis,:].repeat(len(x.index), axis=0),columns=x.columns, index=x.index) 
The slowest run took 8.65 times longer than the fastest. This could mean that an intermediate result is being cached. 
10000 loops, best of 3: 184 µs per loop 
+0

これはかなり任意のインデックスでも動作します...インデックスが一意でない場合は堅牢です。 – piRSquared

+0

ありがとう、ちょうど私の場合4000 +行と2000 + colsでテストされています。 3つの方法に費やされた時間は大体[1.08s、0.59s、0.58s] – wh408

0

ラムダに割り当てることはできませんが、f = lambda x : [column.sum() for column in x]

5
for col in df: 
    df[col] = df[col].sum() 

のように、リスト内包で何かを行うことができますループを使用しない、または遅くソリューション...

df = pd.DataFrame([df.sum()] * len(df)) 

タイミング

@jezraelタイミングをおねがいします。これはより大きなデータフレーム上でそれらを行い、forループも含みます。時間のほとんどは、データフレームを作成するのではなく合計を計算する費やされているので、これはその@ayhanから1のように見えるん最も効率的な方法は、直接値に合計を割り当てます

from string import ascii_letters 

df = pd.DataFrame(np.random.randn(10000, 52), columns=list(ascii_letters)) 

# A baseline timing figure to determine sum of each column. 
%timeit df.sum() 
1000 loops, best of 3: 1.47 ms per loop 

# Solution 1 from @Alexander 
%%timeit 
for col in df: 
    df[col] = df[col].sum() 
100 loops, best of 3: 21.3 ms per loop 

# Solution 2 from @Alexander (without `for loop`, but much slower) 
%timeit df2 = pd.DataFrame([df.sum()] * len(df)) 
1 loops, best of 3: 270 ms per loop 

# Solution from @PiRSquared 
%timeit df.stack().groupby(level=1).transform('sum').unstack() 
10 loops, best of 3: 159 ms per loop 

# Solution 1 from @Jezrael 
%timeit (pd.DataFrame(np.tile(df.sum().values, (len(df.index),1)), columns=df.columns, index=df.index)) 
100 loops, best of 3: 2.32 ms per loop 

# Solution 2 from @Jezrael 
%%timeit 
df2 = pd.DataFrame(df.sum().values[np.newaxis,:].repeat(len(df.index), axis=0), 
       columns=df.columns, 
       index=df.index) 
100 loops, best of 3: 2.3 ms per loop 

# Solution from @ayhan 
%time df.values[:] = df.values.sum(0) 
CPU times: user 1.54 ms, sys: 485 µs, total: 2.02 ms 
Wall time: 1.36 ms # <<<< FASTEST 
+0

ありがとう、forループを回避する方法はありますか? – wh408

+0

この場合、forループは完全に有効です。 – Alexander

+0

はい、私の場合は、何千もの列があり、より効率的な方法を見つけようとしています。 – wh408

2
x.stack().groupby(level=1).transform('sum').unstack() 

enter image description here

+0

です。私のケースで4000+行と2000+ colsでテストしました。時間は約10秒です – wh408

4

あなたDATAFRAMEが数字で構成されている場合は、直接その値を変更することができます。

df.values[:] = df.sum() 
+0

これは非常に速いです! – piRSquared

+2

さらに良いことに 'df.values [:] = df.values.sum(0)' – piRSquared

+0

はい、これまでのところ最速のようですが、値が無限に収束するのでテストが難しいです。タイミングに影響を与える可能性があります。 – ayhan

関連する問題