Python np.where()只计算一次np.random.choice()
我有这个数据框:Python np.where()只计算一次np.random.choice(),python,pandas,numpy,Python,Pandas,Numpy,我有这个数据框: np.random.seed(0) N = 10000 N_Seg = 100 df = pd.DataFrame({"Rut_Num": range(1,N+1), "Segmento": np.random.choice( ["Afluente", "Afluente","Premium", "Preferente", "Preferente", "Preferente", "Preferente",
np.random.seed(0)
N = 10000
N_Seg = 100
df = pd.DataFrame({"Rut_Num": range(1,N+1),
"Segmento": np.random.choice(
["Afluente", "Afluente","Premium", "Preferente", "Preferente", "Preferente", "Preferente", "Clásico", "Clásico", "Clásico", "Clásico", "Clásico", "Clásico"], N),
"If_Seguro": np.random.choice([0,1,1], N)})
df.head()
Rut_Num Segmento If_Seguro
0 1 Clásico 1
1 2 Preferente 0
2 3 Afluente 0
3 4 Preferente 0
4 5 Clásico 1
当列If_Seguro
为1时,我需要一个介于1和N_Seg+1
之间的随机数,如果为0,我需要一个0:
np.random.seed()
df.loc[:,"id_Seguro"] = np.where(df["If_Seguro"] == 1, np.random.choice(range(1,N_Seg+1),1),0)
df["id_Seguro"].value_counts()
您可以看到,np.where()
true条件将为所有1提供相同的数字,而我需要从If\u Seguro
If中为每个1提供一个随机数
此外,为什么
np.where()
只对整列计算np.random.choice()
一次,而不对列中的每个验证(每行)进行计算?表达式np.where(df[“If_Seguro”]==1,np.random.choice(范围(1,N_Seg+1),1),0)
显示了我认为经常遇到的问题,但通常不希望在其中使用。该解决方案还将回答您的问题,即为什么只生成一个值
np.其中
计算量不大。它只是根据一对现有数组中的掩码选择值。正常的python语义在这里不会改变。您传递的是函数调用的结果,而不是函数本身,因此使用的是值。这意味着您需要为df
的所有行计算np.random.choice(…)
,而不仅仅是那些df[“If_Seguro”]==1的行
df[“If_Seguro”]
是一个面具,numpy为你提供了一些面具烦恼的工具。例如,要生成的实际元素数为
np.count_nonzero(df["If_Seguro"])
要插入这些值的行位置由掩码本身提供。numpy和pandas都允许您直接使用布尔掩码进行索引<代码>np。在许多情况下,
只是效率低下的额外一层
最后,要从现有序列生成N个样本,请执行以下操作之一:
np.random.choice(range(1, N_Seg + 1), size=N, replace=True)
replace=True
允许重复样本,就像您最初对np.where
的调用一样。做同样事情的更好方法不涉及显式序列对象:
np.random.randint(1, N_Seg + 1, N)
在建议的解决方案中,其中将是屏蔽元素的数量,而在原始代码中,它应该是N
因此,最后我们有:
mask = df["If_Seguro"]
df.loc[mask, "id_Seguro"] = np.random.randint(1, 1 + N_Seg, np.count_nonzero(mask))
如果id\u Seguro
一开始还没有归零,您可以做以下几件事之一。在前面的基础上增加:
df.loc[~mask, "id_Seguro"] = 0
或者从头开始生成新阵列:
mask = df["If_Seguro"]
result = np.zeros(N)
result[mask] = np.random.randint(1, 1 + N_Seg, np.count_nonzero(mask))
df["id_Seguro"] = result
感谢您提及numpy.where()
的非常普遍(ab)的用法!