查找跨列位平均值的有效方法

时间:2019-04-18 23:09:47

标签: python pandas

考虑一个df,其中包含N列和M行,其中每个条目都是8位整数。 N和M非常大。让我们以N=5M=10为例:

>>> df = pd.DataFrame(np.random.randint(1, 10, (10, 5)), columns=list('abcde'))

>>> df
   a  b  c  d  e
0  2  4  8  9  9
1  1  1  1  1  6
2  9  7  5  2  2
3  8  1  8  6  4
4  8  6  7  9  5
5  9  6  5  9  9
6  1  3  2  3  3
7  6  5  9  9  5
8  6  5  2  9  3
9  1  7  9  7  1

我想找到每列8位的平均值,并为每列创建一个新列。

在我们的示例中,这将导致以下结果(仅在第一行显示):

>>> df
   a  b  c  d  e  Bit7 Bit6 Bit5 Bit4  Bit3    Bit2    Bit1    Bit0
0  2  4  8  9  9   0    0    0    0   3/5=0.6 1/5=0.2 1/5=0.2 2/5=0.4
1  1  1  1  1  6
2  9  7  5  2  2
3  8  1  8  6  4
4  8  6  7  9  5
5  9  6  5  9  9
6  1  3  2  3  3
7  6  5  9  9  5
8  6  5  2  9  3
9  1  7  9  7  1
通过平均LSB Bit0{0 (from col a), 0 (from col b), 0 (from col c), 1 (from col d), 0 (from col e)}列和Bit1的平均值来创建 {1,0,0,0,0}列,依此类推,直到与列的MSB。

要牢记Bit7N很大,有什么有效的方法?

1 个答案:

答案 0 :(得分:2)

我认为除了一次找到一个平均值以外,没有其他方法可以解决此问题。 DataFrame.apply()是对数据框执行操作的好方法。

import pandas as pd
import numpy as np

N=5
M=10
df = pd.DataFrame(np.random.randint(1, M, (M, N)), columns=list('abcde'))


for bitNum in range(8):
    df[f'Bit{bitNum}'] = df.apply(lambda row : (sum([1 & (row[i] >> bitNum)  for i in range(N)])), axis=1)

for bitNum in range(8):
    df[f'Bit{bitNum}'] = df[f'Bit{bitNum}'].apply(lambda x : float(x)/N)

您会注意到,上面的代码对所有总和完成后进行除法以获得平均值。我在编写此代码时遇到了一个奇怪的问题。如果您尝试在第一个lambda函数中将除以$ N $,则它将抱怨您在浮点数上执行<<并将其与整数进行比较。但是,如果我打印了df行,然后再次尝试行了,也许有人可以解释。无论如何,我相信上面的答案有效!

编辑:如果您使用的是Python 3,则可以在第二个循环中跳过浮点转换。