将每列中的值指定为该列的总和

时间:2016-08-12 14:20:23

标签: python pandas lambda

我有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,axis = 0),但我不知道如何定义一个将列转换为lambda函数中所有列值之和的函数。以下行引发SyntaxError:无法分配给lambda

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

5 个答案:

答案 0 :(得分:5)

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

或没有使用循环的较慢解决方案...

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

<强>计时

@jezrael感谢您的时间安排。这可以在更大的数据帧上进行,也包括for循环。大部分时间都花在创建数据框而不是计算总和上,因此最有效的方法似乎是来自@ayhan的直接为值分配总和的方法:

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

答案 1 :(得分:5)

使用numpy.tile的另一个更快速的numpy解决方案:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/leftTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <EditText
        android:id="@+id/editText"
        android:layout_toEndOf="@+id/leftTextView"
        android:layout_toStartOf="@+id/rightTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content/>

    <TextView
        android:id="@+id/rightTextView"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>

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

答案 2 :(得分:4)

如果您的DataFrame由数字组成,您可以直接更改其值:

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

答案 3 :(得分:2)

使用transform

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

enter image description here

答案 4 :(得分:0)

我不确切地知道你要做什么,但你可以对列表理解做些什么,比如f = lambda x : [column.sum() for column in x]