从MultiIndex DataFrame中采样

时间:2016-01-20 01:53:18

标签: python pandas dataframe sampling

我在名为MultiIndex的{​​{1}}大熊猫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 索引一个人(其中有500人),n索引时间。它是一个平衡的面板。我想创建一个t个人的随机样本。此外,如果个人将其纳入随机样本,则应将该个体的所有4次观察(t = 0,1,2,3)分配给样本。

以下几行几乎是我想要的:

nn=100

但是,它不会反复对个人进行抽样。因此,如果创建的随机变量列表是[2,3,2,4,1,...],则第三个人(index = 2是第三个人)仅被选择一次而不是随机样本的两次。这意味着只要上面的随机向量包含同一个体不止一次,我就会在随机样本中得到少于100个个体(每次有4次观察)。 我也尝试了df_sample = df_data.loc[np.random.randint(3, size=100).tolist()] 函数,但我似乎无法处理面板中的特定多级索引。 我可以编写各种循环来完成这项工作,但我认为应该有一种更简单(更快)的方法。 我使用的是Python 3.5,而且我使用的是pandas版本0.17.1。 感谢。

3 个答案:

答案 0 :(得分: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()

答案 1 :(得分: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

使用np.random.randinttime的结果与product值结合起来:

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), ...]

并相应地选择:

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)

答案 2 :(得分:1)

这对我有用,它与其他答案有关:

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的样本及其所有相关的“其他”。