Есть ли более быстрая альтернатива получению подмножества DataFrame? - PullRequest
0 голосов
/ 26 сентября 2018

В настоящее время я работаю над некоторым кодом Python, где я пытаюсь получить подмножество DataFrame, где значение столбца равно определенному значению.Я делаю это так:

for i in brands.index:
    current_brand = brands.get_value(i, 'Car Brand')
    my_dataframe_subset = my_dataframe[my_dataframe['Brand'] == current_brand]  

Это, конечно, работает при создании подмножества, но я делаю это непрерывно в цикле, тысячи раз.Я обнаружил, что это огромное узкое место в моей скорости выполнения, но, к сожалению, «current_brand» меняет каждую итерацию цикла, поэтому я не вижу другого пути.Есть ли более быстрая альтернатива получению этого подмножества, которое не вызвало бы такой огромной задержки?

Спасибо

РЕДАКТИРОВАТЬ : Это более реалистичный пример того, что делает мой код.Очевидно, что данные бессмысленны, но я надеюсь, что вы поняли:

------------------------
|Person | Car Brand |
|------------------------
|'dave' | 'Toyota'  |
|'mike' | 'Ford'    |
|'sally'| 'Ford'    |
|'doug' | 'BMW'     |
------------------------
my_list = []
for i in brands.index:
    current_person = brands.get_value(i, 'Person')
    current_brand = brands.get_value(i, 'Car Brand')
    my_dataframe_subset = my_dataframe[my_dataframe['Brand'] == current_brand] 

    for i_b in my_dataframe_subset.index:
        #do stuff with current_person and current_brand
        car_colour = my_dataframe_subset(i_b, 'Colour')
        car_speed = my_dataframe_subset(i_b, 'Speeds')
        my_dict = {'person': current_person, 'brand': current_brand, 'colour': car_colour, 'speed': car_speed}
        my_list.append(my_dict)

Ответы [ 3 ]

0 голосов
/ 26 сентября 2018

Давайте начнем с некоторых примеров данных:

import pandas
brands = pandas.DataFrame({'Car Brand': ['Toyota', 'Honda']})
my_dataframe = pandas.DataFrame({'Brand': ['Toyota']*4 + ['Honda']*4, 'Value': [1]*8})

Для ситуации с этими данными в кадре данных brands содержатся только уникальные значения в столбце my_dataframe.Brand.В этом случае вы можете использовать groupby напрямую:

for current_brand, my_dataframe_subset in my_dataframe.groupby('Brand'):
    # do stuff with subset

Если в brands меньше брендов, чем в my_dataframe, вы можете отфильтровать их:

dataset_for_brands = my_dataframe[my_dataframe.Brand.isin(brands['Car Brand'])]
for current_brand, my_dataframe_subset in dataset_for_brands.groupby('Brand'):
    # do stuff with subset

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

my_dataframe.groupby('Brand').Value.mean()

и получите ответ напрямую:

Brand
Honda     1
Toyota    1
0 голосов
/ 26 сентября 2018

1) Итерация по всем уникальным брендам из brands кадра данных.

2) Фильтрация строк в my_dataframe кадре данных, соответствующих бренду.

В зависимости от того, как вы хотитеобрабатывать пустые наборы (т. е. когда brand в my_dataframe не совпадает с набором из brands), вы можете просто сгруппировать по Brand в my_dataframe, как показано @jezrael и @ chthonicdaemon.

for current_brand in brands['Car Brand'].unique():
    brand_df = my_dataframe[my_dataframe['Brand'] == current_brand]
    # Do stuff with filtered brand dataframe.
0 голосов
/ 26 сентября 2018

Я думаю, нужно merge с внутренним объединением по умолчанию:

brands = pd.DataFrame({
        'Person': ['dave', 'mike', 'sall', 'doug'], 
        'Car Brand': ['Kia', 'Ford', 'Ford', 'BMW']
})

my_dataframe = pd.DataFrame({
        'Brand':['Toyota','Toyota','BMW', 'BMW', 'BMW', 'Ford'],
         'Speeds':[40,50,20,10,30,40],
         'Colour':list('abcdef')
})
print (my_dataframe)
    Brand  Speeds Colour
0  Toyota      40      a
1  Toyota      50      b
2     BMW      20      c
3     BMW      10      d
4     BMW      30      e
5    Ford      40      f

d = {'Car Brand':'Brand'}
df = brands.rename(columns=d).merge(my_dataframe, on='Brand')
print (df)
  Person Brand  Speeds Colour
0   mike  Ford      40      f
1   sall  Ford      40      f
2   doug   BMW      20      c
3   doug   BMW      10      d
4   doug   BMW      30      e

Если нужен список словарей:

my_list = df.to_dict(orient='records')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...