Python 从多索引数据帧采样
我正在使用名为Python 从多索引数据帧采样,python,pandas,dataframe,sampling,Python,Pandas,Dataframe,Sampling,我正在使用名为df_data的多索引DataFrame中的以下面板数据: 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.4
df_data
的多索引DataFrame
中的以下面板数据:
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次观察)。
我还尝试了dfu data.sample
函数,但似乎无法处理面板中的特定多级索引。
我可以编写各种循环来完成这项工作,但我认为应该有一种更简单(更快)的方法。
我使用的是Python 3.5,我使用的是pandas版本0.17.1。
谢谢。您可以使用itertools.product
快速生成从多索引中选择副本所需的格式:
样本数据:
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.randint
的结果与时间
值相结合:
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 = 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及其所有相关“其他”的样本。嗨,Stefan,这是一个很好的解决方案,比我昨晚做的快30倍左右。要添加到解决方案中的一件事是重新为样本编制索引,以便索引再次唯一,并且可以在其上运行一些pandas函数(如OLS等)。类似这样:individualsb=list(range(100))
和indexb=pd.MultiIndex.from_tuples(list(product(individualsb,time))
和sample=sample.set_index(indexb)
不客气,更新以消除多索引中的重复。鉴于使用了子索引,我不清楚是否会多次采样。isin(样本ID)
?请注意,这不会按照问题的要求实现替换采样