Дольше, чем решение Эрфана; Я просто считаю, что это может помочь избежать увеличения числа строк в результате слияния. То, что это делает, ищет cond1 и cond2, которые соответствуют предложению where в запросе sql. На следующем шаге происходит сжатие обоих списков и поиск индекса элемента (True, True) ... полученный индекс является эквивалентом индекса для df_types. объединить все кадры данных, извлеченные из df_types на основе индексов, и снова выполнить конкататацию в df_products. Должно быть лучше, чем это; Однако я верю, что SQL делает это лучше.
cond1 = df_products['size'].apply(lambda x: [x>=i for i in [*df_types.size_min.array]])
cond2 = df_products['size'].apply(lambda x: [x<i for i in [*df_types.size_max.array]])
t = [list(zip(i,j)).index((True,True))
for i,j in zip(cond1.array,cond2.array)]
result = (pd.concat([df_types.iloc[[i]]
for i in t])
.filter(['type'])
.reset_index(drop=True))
outcome = (pd.concat([df_products,result],
axis=1,
ignore_index=True,
join='outer'))
outcome.columns = ['id_product', 'size', 'type']
id_product size type
0 A 6 M
1 B 25 XL
2 C 7 M
3 D 2 S
4 F 45 XL
5 E 10 M
6 G 16 L
Обновление : время идет, и, надеюсь, мы поправляемся. сделал еще один выстрел, но переместил транзакцию в ваниль python, прежде чем вернуть окончательный результат обратно в Pandas:
from itertools import product
test = [(id_product,first,last)
for (id_product,first), (second, third,last)
in product(zip(df_products.id_product,df_products['size']),
df_types.to_numpy()
)
if second <= first <= third
]
test
[('A', 6, 'M'),
('B', 25, 'XL'),
('C', 7, 'M'),
('D', 2, 'S'),
('F', 45, 'XL'),
('E', 10, 'M'),
('G', 16, 'M'),
('G', 16, 'L')]
, чтобы получить pandas фрейм данных:
pd.DataFrame(test,columns=['id_product', 'size', 'type'])
id_product size type
0 A 6 M
1 B 25 XL
2 C 7 M
3 D 2 S
4 F 45 XL
5 E 10 M
6 G 16 M
7 G 16 L
обратите внимание, что последний элемент 'G' возвращает две строки, так как он соответствует тем, в зависимости от условий.