Эффективное извлечение подмножества данных из Pandas Dataframe - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть 6 панелей данных (Пациенты, Тест1, Тест2, Тест3, Тест4, Тест5), связанных ключом ID.

Каждая строка в фрейме данных «Пациенты» представляет пациента с уникальным идентификатором, в котором содержится более 200 000 пациентов / строк.

Каждая строка в тестовых фреймах данных представляет результат теста за день. Столбцы для тестовых фреймов данных: ID, DATE, TEST_UNIT, TEST_RESULT. Каждый из тестовых фреймов данных содержит от 6 000 000 до 7 000 000 строк.

Я хочу перебрать все идентификаторы в кадре данных Patients и в каждой итерации использовать этот идентификатор, чтобы извлечь соответствующие тестовые данные из каждого из 5 тестовых информационных фреймов и выполнить некоторую обработку на них.

Если я делаю

for i in range(len(Patients)):
    ind_id = Patients.ID.iloc[i]
    ind_test1 = Test1[Test1['ID'] == ind_id]
    ind_test2 = Test2[Test2['ID'] == ind_id]
    ind_test3 = Test3[Test3['ID'] == ind_id]
    ind_test4 = Test4[Test4['ID'] == ind_id]
    ind_test3 = Test5[Test5['ID'] == ind_id]

На каждую итерацию уходит около 3,6 секунды.

Когда я пытался ускорить его с помощью интерфейса Numpy.

Patients_v = Patients.values
Test1_v = Test1.values
Test2_v = Test2.values
Test3_v = Test3.values
Test4_v = Test4.values
Test5_v = Test5.values

for i in range(len(Patients_v)): 
    ind_id = Patients_v[i, ID_idx]
    ind_test1 = Test1_v[Test1_v[:, 0] == ind_id]
    ind_test2 = Test2_v[Test2_v[:, 0] == ind_id] 
    ind_test3 = Test3_v[Test3_v[:, 0] == ind_id] 
    ind_test4 = Test4_v[Test4_v[:, 0] == ind_id] 
    ind_test5 = Test5_v[Test5_v[:, 0] == ind_id]  

Это занимает около 0,9 секунды на итерацию.

Как я могу ускорить это?

Спасибо

1 Ответ

0 голосов
/ 08 ноября 2018

Неясно, какой выход вы желаете. Мы можем только предполагать, что вам нужны специфичные для пациента данные.

В любом случае ваш текущий код должен будет содержать все кадры данных в памяти. Это неэффективно. Посмотрите, например, на функции генератора :

1. Создать список всех идентификаторов

ALL_IDS = Patients.IDs.tolist()                        # Assuming all you need is the ID

2. Создать рамку основных данных

ALL_DFS = [Test1, Test2, Test3, Test4, Test5]
df_master = pd.concat(ALL_DFS)

3. Создать функцию генератора, которая выдает специфичные для пациента кадры данных для дальнейшей обработки

def patient_slices(ALL_IDS):                           # Generator
    for ID in ALL_IDS:
        df_slice = df_master[df_master.ID == ID]
        yield df_slice

df_slice = patient_slices(ALL_IDS)                      
for _ in xrange(len(ALL_IDS)):                         # Call the generator n times
    sinlge_patient = next(df_slice)                    # Next patient for every call    
    your_processing(sinlge_patient)                    # Do your magic
...