Как выбрать каждую группу из фрейма данных pandas с разной скоростью - PullRequest
3 голосов
/ 04 апреля 2019

У меня есть фрейм данных, содержащий информацию о населении, из которого я хочу сгенерировать выборку.У меня также есть фрейм данных sample_info, в котором указано, сколько единиц каждой группы в фрейме данных population мне нужно в моем образце.Я разработал некоторый код, который достигает того, что мне нужно, но он работает медленнее, чем хотелось бы, учитывая большие наборы данных, с которыми я работаю.

Есть ли способ сгруппировать структуру населения и применить выборку к группам, а нецикл через них, как я сделал ниже?

import pandas as pd

population = pd.DataFrame([[1,True],[1,False],[1,False],[2,True],[2,True],[2,False],[2, True]], columns = ['Group ID','Response'])

    Group ID    Response
0   1           True
1   1           False
2   1           False
3   2           True
4   2           True
5   2           False
6   2           True

sample_info = pd.DataFrame([[1,5],[2,6]], columns = ['Group ID','Sample Size'])

output = pd.DataFrame(columns = ['Group ID','Response'])

    Group ID    Sample Size
0   1           5
1   2           6


for index, row in sample_info.iterrows():    
        output = output.append(population.loc[population['Group ID'] == row['Group ID']].sample(n=row['Sample Size'], replace = True)) 

Я не мог придумать, чтобы ввести информацию о размере выборки, используя group-by, и применить, как предложено в Pandas: выборка каждой группы после groupby

Ответы [ 2 ]

3 голосов
/ 04 апреля 2019

Конвертировать sample_info в словарь.Группа населения по идентификатору группы.Передайте значения размера выборки в DataFrame.sample, используя словарь.

mapper = sample_info.set_index('Group ID')['Sample Size'].to_dict()

population.groupby('Group ID').apply(lambda x: x.sample(n=mapper.get(x.name))).reset_index(drop = True)
2 голосов
/ 04 апреля 2019

Я не уверен насчет скорости, но сэмпл, на который похож индекс, сохраняет память как минимум

d=population.groupby('Group ID').groups
a=np.concatenate([np.random.choice(d[x],y) for x, y in zip(sample_info['Group ID'],sample_info['Sample Size']) ])
population.loc[a]
Out[83]: 
   Group ID  Response
1         1     False
1         1     False
2         1     False
0         1      True
1         1     False
3         2      True
5         2     False
3         2      True
4         2      True
5         2     False
5         2     False
...