考虑一个df
,其中包含N
列和M
行,其中每个条目都是8位整数。 N和M非常大。让我们以N=5
和M=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。
要牢记Bit7
和N
很大,有什么有效的方法?
答案 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,则可以在第二个循环中跳过浮点转换。