Использование pandas dataframe в качестве справочной таблицы - PullRequest
0 голосов
/ 24 апреля 2018

Учитывая одну строку из фрейма данных X, какой самый эффективный способ извлечь все строки из фрейма данных Y, которые полностью соответствуют строке запроса?

Пример: запрос строки [0,1,0,1] из

[
 [0,1,0,1, 1.0],
 [0,1,0,1, 2.0],
 [0,1,0,0, 3.0],
 [1,1,0,0, 0.5],
]

должен вернуть

[
 [0,1,0,1, 1.0],
 [0,1,0,1, 2.0],
]

X и Y, как предполагается, имеют одну и ту же схему, за исключением того, что Y имеет дополнительный столбец целевого значения.Может быть один, ноль или много совпадений.Решение должно быть эффективным даже с тысячами столбцов.

Ответы [ 3 ]

0 голосов
/ 24 апреля 2018

Я бы пошел с объединить :

import pandas as pd

y = pd.DataFrame({'A': [1, 1, 3],
                  'B': list('aac'),
                  'C': list('ddf'),
                  'D': [4, 5, 6]})

x = pd.DataFrame([[1, 'a', 'd']],
                 columns=list('ABC'))

match = x.merge(y, on=x.columns.tolist())

match
#   A  B  C  D
#0  1  a  d  4
#1  1  a  d  5
0 голосов
/ 24 апреля 2018

Один эффективный способ - перейти к numpy и запросить отдельные столбцы:

Данные @ Jezrael.

import pandas as pd, numpy as np

df = pd.DataFrame({'A':list('abadef'),
                   'B':[4,5,4,5,5,4],
                   'C':[7,8,7,4,2,3],
                   'D':[1,3,1,7,1,0],
                   'E':[5,3,5,9,2,4],
                   'F':list('aaabbb')})

vals = df.values
arr = [4, 7, 1, 5]

mask = np.logical_and.reduce([vals[:, i+1]==arr[i] for i in range(len(arr))])
res = df.iloc[np.where(mask)[0]]

print(res)

#    A  B  C  D  E  F
# 0  a  4  7  1  5  a
# 2  a  4  7  1  5  a
0 голосов
/ 24 апреля 2018

Использование boolean indexing:

L = [
 [0,1,0,1, 1.0],
 [0,1,0,1, 2.0],
 [0,1,0,0, 3.0],
 [1,1,0,0, 0.5],
]
df = pd.DataFrame(L)

Y = [0,1,0,1]


print (df[df.iloc[:, :len(Y)].eq(Y).all(axis=1)])

   0  1  2  3    4
0  0  1  0  1  1.0
1  0  1  0  1  2.0

Объяснение

Сначала выберите первые N столбцы по длине последовательности:

print (df.iloc[:, :len(Y)])
   0  1  2  3
0  0  1  0  1
1  0  1  0  1
2  0  1  0  0
3  1  1  0  0

Сравнить все строки по первой строке, выбранной с помощью eq и loc:

print (df.iloc[:, :len(Y)].eq(Y))
       0     1     2      3
0   True  True  True   True
1   True  True  True   True
2   True  True  True  False
3  False  True  True  False

И проверьте соответствие на DataFrame.all для проверки всех True с в строке:

print (df.iloc[:, :len(Y)].eq(Y).all(1))
0     True
1     True
2    False
3    False
dtype: bool
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...