Эффективно найти индекс значений DataFrame в массиве - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть DataFrame, похожее на:

x     y     z
--------------
0     A     10
0     D     13
1     X     20
...

, и у меня есть два отсортированных массива для каждого возможного значения для x и y:

x_values = [0, 1, ...]
y_values = ['a', ..., 'A', ..., 'D', ..., 'X', ...]

, поэтомуЯ написал функцию:

def lookup(record, lookup_list, lookup_attr):
    return np.searchsorted(lookup_list, getattr(record, lookup_attr))

и затем вызвал:

df_x_indicies = df.apply(lambda r: lookup(r, x_values, 'x')
df_y_indicies = df.apply(lambda r: lookup(r, y_values, 'y')

# df_x_indicies: [0, 0, 1, ...]
# df_y_indicies: [26, ...]

но есть ли более эффективный способ сделать это?и, возможно, несколько столбцов одновременно, чтобы получить возвращенный DataFrame, а не ряд?

Я пытался:

np.where(np.in1d(x_values, df.x))[0]

, но это удаляет повторяющиеся значения, а это нежелательно.

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Вы можете конвертировать ваши индексные массивы в pd.Index объекты, чтобы сделать поиск быстрым (er).

u, v = map(pd.Index, [x_values, y_values])
pd.DataFrame({'x': u.get_indexer(df.x), 'y': v.get_indexer(df.y)})

   x  y
0  0  1
1  0  2
2  1  3

Где,

x_values
# [0, 1]

y_values
# ['a', 'A', 'D', 'X']

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

val_list = [x_values, y_values] # [x_values, y_values, z_values, ...]
idx_list = map(pd.Index, val_list)
pd.DataFrame({
    f'{c}': idx.get_indexer(df[c]) for idx, c in zip(idx_list, df)})

   x  y
0  0  1
1  0  2
2  1  3
0 голосов
/ 18 декабря 2018

Обновление с помощью Series с .loc, вы также можете попробовать с reindex

pd.Series(range(len(x_values)),index=x_values).loc[df.x].tolist()
Out[33]: [0, 0, 1]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...