从 MultiIndex DataFrame 中采样
Sampling from MultiIndex DataFrame
我正在 MultiIndex
pandas DataFrame
中使用以下面板数据 df_data
:
y x
n time
0 0 0.423607 -0.307983
1 0.565563 -0.333430
2 0.735979 -0.453137
3 0.962857 1.671106
1 0 0.772304 1.221366
1 0.455327 -1.024852
2 0.864768 0.609867
3 0.334429 -2.567936
2 0 0.435553 -0.259228
1 0.221501 0.484677
2 0.773628 0.650288
3 0.293902 0.566452
n
索引一个人(有 500 个),t
索引时间。这是一个平衡的面板。我想创建一个 nn=100
个人的随机样本并进行替换。此外,如果某个人进入随机样本,则应将此人的所有 4 次观察 (t=0,1,2,3) 分配给样本。
下面这行几乎是我想要的:
df_sample = df_data.loc[np.random.randint(3, size=100).tolist()]
但是,它不会重复对一个人进行采样。因此,如果创建的随机变量列表是 [2, 3, 2, 4, 1, ...],那么第三个人(索引 =2 是第三个人)仅被选择一次而不是两次进入随机样本。这意味着只要上面的随机向量多次包含同一个体,我最终在随机样本中得到的个体少于 100 个(每个个体有 4 次观察)。
我也尝试了 df_data.sample
功能,但我似乎无法处理面板中的特定多级索引。
我可以编写各种循环来完成这项工作,但我认为应该有一种更简单(更快)的方法来完成这项工作。
我使用的是 Python 3.5,我使用的是 pandas 版本 0.17.1。
谢谢。
您可以使用 itertools.product
通过 MultiIndex
:
的重复项快速生成 select 所需的格式
示例数据:
from itertools import product
individuals = list(range(500))
time = (0, 1, 2, 3,)
index = pd.MultiIndex.from_tuples(list(product(individuals, time)))
df = pd.DataFrame(data={'A': np.random.random(size=2000), 'B': np.random.random(size=2000)}, index=index)
A B
0 0 0.208461 0.842118
1 0.481681 0.096121
2 0.420538 0.922363
3 0.859182 0.078940
1 0 0.171162 0.255883
1 0.338864 0.975492
2 0.270533 0.504605
3 0.691041 0.709189
2 0 0.220405 0.925001
1 0.811951 0.479795
2 0.010527 0.534866
3 0.561204 0.915972
3 0 0.813726 0.083478
1 0.745100 0.462120
2 0.189111 0.552039
3 0.006141 0.622969
使用 product
将 np.random.randint
的结果与 time
值合并:
sample_ix = np.random.randint(low=0, high=500, size=100)
len(np.unique(sample_ix))
91
sample_multi_ix = list(product(sample_ix, time))
[(55, 0), (55, 1), (55, 2), (55, 3), (254, 0), (254, 1), (254, 2), (254, 3), ...]
和select因此:
sample = df.loc[sample_multi_ix, :]
sample.info()
MultiIndex: 400 entries, (55, 0) to (135, 3)
Data columns (total 2 columns):
A 400 non-null float64
B 400 non-null float64
dtypes: float64(2)
memory usage: 9.4+ KB
如果你想要独一无二的sample
index
,你可以添加:
sample.index = pd.MultiIndex.from_tuples(list(product(list(range(100)), time)))
MultiIndex: 400 entries, (0, 0) to (99, 3)
Data columns (total 2 columns):
A 400 non-null float64
B 400 non-null float64
dtypes: float64(2)
一个简单的解决方案:
subindex = df.index.get_level_values('sub_index')
sample_ids = np.random.choice(subindex, 5, replace=True)
sample = df[subindex.isin(sample_ids)].copy()
这对我有用,它是其他答案的组合:
subindex = df.index.get_level_values('id')
sample_ids = np.random.choice(subindex, 5, replace=False)
sample = df.loc[sample_ids]
我正在使用索引为 ["id"、"other"] 的 df。它返回了 5 个 id 及其所有关联的样本 "others".
我正在 MultiIndex
pandas DataFrame
中使用以下面板数据 df_data
:
y x
n time
0 0 0.423607 -0.307983
1 0.565563 -0.333430
2 0.735979 -0.453137
3 0.962857 1.671106
1 0 0.772304 1.221366
1 0.455327 -1.024852
2 0.864768 0.609867
3 0.334429 -2.567936
2 0 0.435553 -0.259228
1 0.221501 0.484677
2 0.773628 0.650288
3 0.293902 0.566452
n
索引一个人(有 500 个),t
索引时间。这是一个平衡的面板。我想创建一个 nn=100
个人的随机样本并进行替换。此外,如果某个人进入随机样本,则应将此人的所有 4 次观察 (t=0,1,2,3) 分配给样本。
下面这行几乎是我想要的:
df_sample = df_data.loc[np.random.randint(3, size=100).tolist()]
但是,它不会重复对一个人进行采样。因此,如果创建的随机变量列表是 [2, 3, 2, 4, 1, ...],那么第三个人(索引 =2 是第三个人)仅被选择一次而不是两次进入随机样本。这意味着只要上面的随机向量多次包含同一个体,我最终在随机样本中得到的个体少于 100 个(每个个体有 4 次观察)。
我也尝试了 df_data.sample
功能,但我似乎无法处理面板中的特定多级索引。
我可以编写各种循环来完成这项工作,但我认为应该有一种更简单(更快)的方法来完成这项工作。
我使用的是 Python 3.5,我使用的是 pandas 版本 0.17.1。
谢谢。
您可以使用 itertools.product
通过 MultiIndex
:
示例数据:
from itertools import product
individuals = list(range(500))
time = (0, 1, 2, 3,)
index = pd.MultiIndex.from_tuples(list(product(individuals, time)))
df = pd.DataFrame(data={'A': np.random.random(size=2000), 'B': np.random.random(size=2000)}, index=index)
A B
0 0 0.208461 0.842118
1 0.481681 0.096121
2 0.420538 0.922363
3 0.859182 0.078940
1 0 0.171162 0.255883
1 0.338864 0.975492
2 0.270533 0.504605
3 0.691041 0.709189
2 0 0.220405 0.925001
1 0.811951 0.479795
2 0.010527 0.534866
3 0.561204 0.915972
3 0 0.813726 0.083478
1 0.745100 0.462120
2 0.189111 0.552039
3 0.006141 0.622969
使用 product
将 np.random.randint
的结果与 time
值合并:
sample_ix = np.random.randint(low=0, high=500, size=100)
len(np.unique(sample_ix))
91
sample_multi_ix = list(product(sample_ix, time))
[(55, 0), (55, 1), (55, 2), (55, 3), (254, 0), (254, 1), (254, 2), (254, 3), ...]
和select因此:
sample = df.loc[sample_multi_ix, :]
sample.info()
MultiIndex: 400 entries, (55, 0) to (135, 3)
Data columns (total 2 columns):
A 400 non-null float64
B 400 non-null float64
dtypes: float64(2)
memory usage: 9.4+ KB
如果你想要独一无二的sample
index
,你可以添加:
sample.index = pd.MultiIndex.from_tuples(list(product(list(range(100)), time)))
MultiIndex: 400 entries, (0, 0) to (99, 3)
Data columns (total 2 columns):
A 400 non-null float64
B 400 non-null float64
dtypes: float64(2)
一个简单的解决方案:
subindex = df.index.get_level_values('sub_index')
sample_ids = np.random.choice(subindex, 5, replace=True)
sample = df[subindex.isin(sample_ids)].copy()
这对我有用,它是其他答案的组合:
subindex = df.index.get_level_values('id')
sample_ids = np.random.choice(subindex, 5, replace=False)
sample = df.loc[sample_ids]
我正在使用索引为 ["id"、"other"] 的 df。它返回了 5 个 id 及其所有关联的样本 "others".