我正在尝试在数据帧的列之间实现高效的按位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。
计算此多数函数的最佳方法是什么?如果将值存储为整数,则计算多数的方法会有所不同吗?
答案 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']
联接。