将零和一列解释为二进制并将其存储为整数列

时间:2016-06-06 05:01:09

标签: python numpy pandas binary integer

我有一个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

尽可能高效。

3 个答案:

答案 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