首页 > 解决方案 > 列之间的按位多数函数

问题描述

我正在尝试在数据帧的列之间实现有效的按位多数函数。

为了简单起见,我在下面显示了一个转置列(列是 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。

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

标签: pythonpandas

解决方案


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

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]变成[0, 0, 1],变成['0', '0', '1'],连接到'001'


推荐阅读