列之间的按位多数功能

时间:2019-03-29 16:15:51

标签: python pandas

我正在尝试在数据帧的列之间实现高效的按位majority function

为简单起见,我在下面显示一个转置的列(列为0、1、2、3和一个特定的A行)。

         A      
      +-----+
   0  | 000 |
      +-----+
   1  | 111 |
      +-----+
   2  | 001 |
      +-----+
   3  | 001 |
      +-----+

      +-----+
Output| 001 |
      +-----+

通过找到每个位置中最重复的位值来完成计算。例如,LSB的值为[0,1,1,1],因此返回的LSB为1。类似地,其他两位计算为0和0。

计算此多数函数的最佳方法是什么?如果将值存储为整数,则计算多数的方法会有所不同吗?

1 个答案:

答案 0 :(得分:1)

第二次编辑:如果您不将数字分割成列表,而是通过df.str.get()访问字符串的第i个字符,实际上会更容易:

df.T.apply(lambda row: ''.join([str(int(row.str.get(i).astype(int).mean() >= 0.5)) for i in range(3)]))

如果您将数字作为整数而不是字符串,则只需替换提取第i个数字的方法:

n_digits = 3
df.T.apply(lambda row: ''.join([str(int(((row // 2**i) % 2).mean() >= 0.5)) for i in range(n_digits-1, -1, -1)]))

旧答案: 将每个条目转换为整数列表,检查平均值是否至少为0.5,然后将得到的布尔值列表连接回零和一串字符串。

df = pd.DataFrame([['000','111','001','001'],['111','111','101','001']], columns=['0','1','2','3'], index=['A','B'])

(df.T.apply(lambda row: 
           (row.apply(lambda x: pd.Series(list(x))).astype(int).mean() >= 0.5)
           .astype(int))
 .astype(str)
 .apply(lambda x: ''.join(x)))

编辑:让我们从内到外仔细看一下代码:变量x是数字作为字符串的二进制表示。首先将其转换为单个字符列表,然后转换为一系列单个字符,然后转换为一系列整数:

x = '001'
print(list(x))
print(pd.Series(list(x)))
print(pd.Series(list(x)).astype(int))
>>>
['0', '0', '1']
0    0
1    0
2    1
dtype: object
0    0
1    0
2    1
dtype: int32

我们对整个行使用此转换(df.T的一列,请记住,apply默认适用于列)

row = df.loc['A']
print(row.apply(lambda x: pd.Series(list(x))).astype(int))
>>>
   0  1  2
0  0  0  0
1  1  1  1
2  0  0  1
3  0  0  1

接下来是多数功能:如果一列的至少50%的项为1,则第i个数字应为1。我们可以通过计算第i列的均值并将其与0.5进行比较来检查这一点:

print(df.T.apply(lambda row: row.apply(lambda x: pd.Series(list(x))).astype(int).mean() >=0.5))
>>>
       A     B
0  False  True
1  False  True
2   True  True

其余代码将每一列(基本上是布尔值列表)转换为整数列表,再转换为字符串列表,最后转换为单个字符串,因此[False, False, True]变为{ {1}},即成为[0, 0, 1],并与['0', '0', '1']联接。