我有一个pandas DataFrame,其中每个观察(行)代表一个人。
我想将满足特定条件的每个人分配到不同的组。我需要这个,因为我的最终目标是创建一个网络,并将同一组中的人与一些依赖于该组的概率联系起来。
所以,例如,我想把所有6到10岁的孩子分配给学校。最后,我将在同一所学校的孩子之间建立一个特定概率 p 的链接。
我知道我想要模拟的区域的学校的大小分布。 所以我想从这个发行版中画出学校规模,然后“填写”#34;所有6至10岁儿童的学校。
我是熊猫新手:我想要这样做的方法是创建一个新列,用NaN填充,然后只为不同的学生分配一个学校ID。
我们说我的DataFrame df
就是这样:
import pandas as pd
import numpy as np
df = pd.DataFrame({'ID': range(11), 'AGE': [15, 6, 54, 8, 10, 39, 2, 7, 9, 10, 6]})
df
Out[1]:
AGE ID
0 15 0
1 6 1
2 54 2
3 8 3
4 10 4
5 39 5
6 2 6
7 7 7
8 9 8
9 10 9
10 6 10
(顺便说一句,我不知道如何将ID列放在第一位,但无论如何在现实生活中我都是从CSV文件中读取数据帧,这样就没有问题了。 / p>
现在,我想要做的是创建另一个专栏ELEM_SCHOOL_ID
,将其初始化为NaN
,然后只为正确年龄的人分配值。
我到目前为止所取得的成就是:与满足年龄条件的人一起创建DataFrame的子集。
df['IN_ELEM_SCH'] = np.where((df['AGE']>5) & (df['AGE']<11), 'True', 'False')
df
Out[2]:
AGE ID IN_ELEM_SCH
0 15 0 False
1 6 1 True
2 54 2 False
3 8 3 True
4 10 4 True
5 39 5 False
6 2 6 False
7 7 7 True
8 9 8 True
9 10 9 True
10 6 10 True
然后,我需要添加另一列ELEM_SCHOOL_ID
,其中包含每个学生参加的特定小学的ID。
我可以使用以下命令初始化新列:
df["ELEM_SCHOOL_ID"] = np.nan
df
Out[84]:
AGE ID IN_ELEM_SCH SCHOOL_ID
0 15 0 False NaN
1 6 1 True NaN
2 54 2 False NaN
3 8 3 True NaN
4 10 4 True NaN
5 39 5 False NaN
6 2 6 False NaN
7 7 7 True NaN
8 9 8 True NaN
9 10 9 True NaN
10 6 10 True NaN
我现在想做的是:
IN_ELEM_SCHOOL == True
的人),将0
分配给SCHOOL_ID
1
分配给SCHOOL_ID
因此,举例来说,让我们说从分布中抽取的第一个学校规模为n0=2
,第二个n1=3
和第三个n2=4
。
我想最终得到这样的东西:
AGE ID IN_ELEM_SCH SCHOOL_ID
0 15 0 False NaN
1 6 1 True 0
2 54 2 False NaN
3 8 3 True 1
4 10 4 True 2
5 39 5 False NaN
6 2 6 False NaN
7 7 7 True 1
8 9 8 True 1
9 10 9 True 2
10 6 10 True 0
在现实生活中,学校规模分布为对数正态分布。比如,参数mu = 4
和sigma = 1
然后我可以从这个分布中得出:
s = np.random.lognormal(mu, sigma, 100)
但我仍然无法弄清楚如何分配学校。
我为这个问题的篇幅道歉,但我想说清楚。
非常感谢你给我的任何暗示或帮助。
答案 0 :(得分:1)
在分配新数据时,Pandas会自动匹配索引。结帐大熊猫docs on indexing。
注意:您通常不会创建额外的IN_ELEM_SCHOOL
列(即下面代码中的第三行是不必要的)。
mu, sigma = 1, 0.5
m = (5 < df['AGE']) & (df['AGE'] < 11)
df['IN_ELEM_SCHOOL'] = m
s = m[m].sample(frac=1)
n, i = 0, 0
while n < len(s):
num_students = int(np.random.lognormal(mu, sigma))
s[n: n + num_students] = i
i += 1
n += num_students
df['SCHOOL_ID'] = s
df
返回
AGE ID IN_ELEM_SCHOOL SCHOOL_ID
0 15 0 False NaN
1 6 1 True 0.0
2 54 2 False NaN
3 8 3 True 1.0
4 10 4 True 2.0
5 39 5 False NaN
6 2 6 False NaN
7 7 7 True 1.0
8 9 8 True 0.0
9 10 9 True 0.0
10 6 10 True 1.0