微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – 加速将概率转换为二进制特征

我有一个包含3列的数据帧,在每行中我有这一行的概率,特征T的值为1,2和3

import pandas as pd
import numpy as np
np.random.seed(42)
df = pd.DataFrame({"T1" : [0.8,0.5,0.01],"T2":[0.1,0.2,0.89],"T3":[0.1,0.3,0.1]})

对于第0行,T为1,有80%的几率,2为10%,3为10%

我想模拟每行的T值,并将列T1,T2,T3更改为二进制功能.
我有一个解决方案,但它需要循环数据帧的行,它真的很慢(我的真实数据帧有超过100万行):

possib = df.columns
for i in range(df.shape[0]):
    probas = df.iloc[i][possib].tolist()
    choix_transp = np.random.choice(possib,1, p=probas)[0]
    for pos in possib:
        if pos==choix_transp:
            df.iloc[i][pos] = 1
        else:
            df.iloc[i][pos] = 0

有没有办法对这段代码进行矢量化?

谢谢 !

解决方法:

我们可以使用numpy:

result = pd.get_dummies((np.random.rand(len(df), 1) > df.cumsum(axis=1)).idxmin(axis=1))

这将生成一列随机值,并将其与数据帧的逐列cumsum进行比较,从而得到一个值的DataFrame,其中第一个False值显示随机值落入哪个“桶”.使用idxmax,我们可以得到这个桶的索引,然后我们可以用pd.get_dummies转换回来.

例:

import numpy as np
import pandas as pd

np.random.seed(0)
data = np.random.rand(10, 3)
normalised = data / data.sum(axis=1)[:, np.newaxis]

df = pd.DataFrame(normalised)
result = pd.get_dummies((np.random.rand(len(df), 1) > df.cumsum(axis=1)).idxmin(axis=1))

print(result)

输出

   0  1  2
0  1  0  0
1  0  0  1
2  0  1  0
3  0  1  0
4  1  0  0
5  0  0  1
6  0  1  0
7  0  1  0
8  0  0  1
9  0  1  0

一张纸条:

大多数减速来自pd.get_dummies;如果你使用Divakar的pd.DataFrame方法(result.view(‘i1’),index = df.index,columns = df.columns),它会快得多.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐