Повышение эффективности циклического прохождения данных в пандах - PullRequest
0 голосов
/ 31 октября 2018

Я предполагаю, что есть более эффективный способ сравнения, который я делаю.

В настоящее время у меня есть две панды DataFrames.

DataFrame A выглядит так:

    Location    Tier    Other
0   100         1       'Blah'
1   200         1       'Blah'
2   10          1       'Blah'
3   30          1       'Blah'
4   500         1       'Blah'

DataFrame B выглядит так:

    Start   Stop    Tier    Other
0   400     600     1       'Blah'
1   5       20      2       'Blah'

Я хотел бы найти все строки, чьи Location > Start и Location < End и Tier совпадают. Таким образом, в приведенном выше примере строка 4 из DataFrame A имеет Location, который больше 400, но меньше 600, а Tier равно `в обоих DataFrames, поэтому он должен как-то быть возвращен, как добавление к окончательному фрейму данных.

Вот как я сейчас сравниваю:

for i in A():
    matching = matching.append(B[(B.Tier == i.Tier) & (B.Start < i.Location) & (B.Stop > i.Location)], ignore_index=True)
return matching

Есть ли более быстрый способ сделать это, так как мой код работает довольно медленно?

Ответы [ 3 ]

0 голосов
/ 31 октября 2018

Использование numpy трансляция

s1=df2.Start.values<df.Location.values[:,None]
s2=df2.Stop.values>df.Location.values[:,None]
s1&s2
Out[110]: 
array([[False, False],
       [False, False],
       [False,  True],
       [False, False],
       [ True, False]])
df[(s1&s2).any(1)]
Out[111]: 
   Location  Tier   Other
2        10     1  'Blah'
4       500     1  'Blah'
0 голосов
/ 31 октября 2018

Вы можете определить Start и Stop, если в B. есть несколько строк с одним и тем же уровнем.

def matching(row):
    # use the first one
    cur_row = B[B.Tier == row.Tier].iloc[0]
    Start = cur_row.Start
    Stop = cur_row.Stop
    return row.Location > Start and row.Location < End

A[A.apply(matching, axis=1)]

Другой пример:

def matching(row):
    # other example
    cur_rows = B[B.Tier == row.Tier]
    Start = cur_rows.Start.min()
    Stop = cur_rows.Stop.max()
    return row.Location > Start and row.Location < End

A[A.apply(matching, axis=1)]
0 голосов
/ 31 октября 2018

Первое, что приходит мне в голову, это сортировка ваших наборов данных (например, сортировка по местоположению, а затем по уровню для набора A). Затем вы можете использовать алгоритм двоичного поиска, чтобы значительно улучшить время поиска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...