我有一个0和1的数据帧。我想将每个列视为其值是整数的二进制表示。进行此转换的最简单方法是什么?
我想要这个:
df = pd.DataFrame([[1, 0, 1], [1, 1, 0], [0, 1, 1], [0, 0, 1]])
print df
0 1 2
0 1 0 1
1 1 1 0
2 0 1 1
3 0 0 1
转换为:
0 12
1 6
2 11
dtype: int64
尽可能高效。
答案 0 :(得分:4)
类似的解决方案,但更快:
const template = require('./List.html');
export default class ListComponent{
static selector = 'list';
static definition: ng.IComponentOptions = {
template: template,
controller: ListComponent,
bindings: {
'id': '@',
'name': '@'
}
};
id;
name;
constructor(private controllers) { // <-- not working
'ngInject';
}
$onInit() {
let ngModelCtrl = this.controllers[0];
let formCtrl = this.controllers[1];
ngModelCtrl.$isEmpty = function(value) {
return !value || value.length === 0;
};
ngModelCtrl.$render = function() {
this.model = ngModelCtrl;
this.form = formCtrl;
this.selected = ngModelCtrl.$modelValue;
};
}
}
<强>计时强>:
print (df.T.dot(1 << np.arange(df.shape[0] - 1, -1, -1)))
0 12
1 6
2 11
dtype: int64
答案 1 :(得分:2)
您可以从列值创建字符串,然后使用int(binary_string, base=2)
转换为整数:
df.apply(lambda col: int(''.join(str(v) for v in col), 2))
Out[6]:
0 12
1 6
2 11
dtype: int64
不确定效率,乘以2的相关功率然后求和可能会更好地利用快速numpy操作,但这可能更方便。
答案 2 :(得分:1)
与使用dot-product
的{{3}}概念相似,但有一些改进。我们可以通过从前面为dot-product
引入2供电范围阵列来避免转置。这对大型阵列是有益的,因为转置它们会产生一些开销。此外,对于这些数字运算情况,在NumPy数组上运行会更好,因此我们可以在df.values
上运行。最后,我们需要转换为pandas series / dataframe以获得最终输出。
因此,结合这两个改进,修改后的实现将是 -
pd.Series((2**np.arange(df.shape[0]-1,-1,-1)).dot(df.values))
运行时测试 -
In [159]: df = pd.DataFrame(np.random.randint(0,2,(4,10000)))
In [160]: p1 = pd.Series((2**np.arange(df.shape[0]-1,-1,-1)).dot(df.values))
# @jezrael's solution
In [161]: p2 = (df.T.dot(1 << np.arange(df.shape[0] - 1, -1, -1)))
In [162]: np.allclose(p1.values, p2.values)
Out[162]: True
In [163]: %timeit pd.Series((2**np.arange(df.shape[0]-1,-1,-1)).dot(df.values))
1000 loops, best of 3: 268 µs per loop
# @jezrael's solution
In [164]: %timeit (df.T.dot(1 << np.arange(df.shape[0] - 1, -1, -1)))
1000 loops, best of 3: 554 µs per loop