我有一个 pandas DataFrame,其中每个观察(行)代表一个人。
我想将每个满足特定条件的人分配到不同的组。我需要这个,因为我的最终目标是创建一个网络,并将同一组中的人员联系起来,其概率取决于组。
例如,我想将所有 6 岁到 10 岁之间的 child 分配到学校。最后我将以特定的概率p在同一所学校的 child 之间建立联系。
我知道我想要模拟的区域中学校的规模分布。 所以我想从这个分布中得出学校规模,然后用所有 6 到 10 岁的 child “填满”学校。
我是 pandas 的新手:我想这样做的方法是创建一个新列,用 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 文件读取数据帧,所以这不是问题)。
现在,我想做的是创建另一列 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
我现在想做的是:
- 从学校规模分布中得出一个数字:n0
- 对于满足年龄条件的 n0 个随机人(因此具有
IN_ELEM_SCHOOL == True
的人),将0
分配给SCHOOL_ID
- 从学校规模分布中得出另一个数字:n1
- 对于尚未分配到学校的随机 n1 个人,将
1
分配给SCHOOL_ID
- 重复此操作,直到所有 IN_ELEM_SCH == True 的人都获得了学校 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)
但我仍然不知道如何分配学校。
对于这个问题的长度,我深表歉意,但我想澄清一下。
非常感谢您给我的任何提示或帮助。
最佳答案
分配新数据时,Pandas 会自动匹配索引。查看 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
关于python - 如何根据特定分布将 DataFrame 观察值分配给组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48792334/