我有一个包含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 举报,一经查实,本站将立刻删除。