python - 如何根据特定分布将 DataFrame 观察值分配给组?

标签 python pandas dataframe

我有一个 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

我现在想做的是:

  1. 从学校规模分布中得出一个数字:n0
  2. 对于满足年龄条件的 n0 个随机人(因此具有 IN_ELEM_SCHOOL == True 的人),将 0 分配给 SCHOOL_ID
  3. 从学校规模分布中得出另一个数字:n1
  4. 对于尚未分配到学校的随机 n1 个人,将 1 分配给 SCHOOL_ID
  5. 重复此操作,直到所有 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 = 4sigma = 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/

相关文章:

python - DataFrame.替换为嵌套字典

r - 使用变量向数据框添加列

python - 覆盖 pandas KDE 和直方图时正确渲染 y 轴

r - 将 lm 输出列表转换为数据帧

c# - 一些 Python 函数的 .NET 等价物

python - 设置网格线上点之间的距离

python - 预配置的 Python Web 框架,具有身份验证、配置文件等

python - 在 Pandas 中使用 multiIndexing 时显示所有索引值

python - 是否可以在日期时间集合上使用 cut?

python - 通过与 Pandas 中的另一个数据框匹配来替换列表列的有效方法