我想在Pandas餐厅坐两张table.
- df_types**包含product类型的范围大小(5000行)
| Table: TYPES | | |
|--------------|----------|------|
| size_max | size_min | type |
| 1 | 5 | S |
| 6 | 16 | M |
| 16 | 24 | L |
| 25 | 50 | XL |
Pandas中的 Dataframe 代码:
df_types = pd.DataFrame([[1,5,'S'],
[6,16,'M'],
[16,24,'L'],
[25,50,'XL']],
columns = ['size_min','size_max','type'])
- df_products**包含产品ID和大小(12000行)
| Table: Products | |
|-----------------|------|
| id_product | size |
| A | 6 |
| B | 25 |
| C | 7 |
| D | 2 |
| F | 45 |
| E | 10 |
| G | 16 |
Pandas中的 Dataframe 代码:
df_products = pd.DataFrame([['A',6,],
['B',25],
['C',7],
['D',2],
['F',45],
['E',10],
['G',16]],columns = ['id_product','size'])
我想在Pandas中创建这个SQL连接:
SELECT *.df_products
type.df_types
FROM df_products LEFT JOIN df_types
ON df_products.size >= df_types.size_min
AND df_products.size <= df_types.size_max
- 结果:**
| id_product | size | type |
|------------|------|------|
| A | 6 | M |
| B | 25 | XL |
| C | 7 | M |
| D | 2 | S |
| F | 45 | XL |
| E | 10 | M |
| G | 16 | M |
谢谢! -)
2条答案
按热度按时间mv1qrgav1#
方法1:
outer join
与pd.merge
虽然这是
SQL
的常见操作,但对于pandas
,没有直接的方法。这里的解决方案之一是执行
outer join
以匹配所有行,然后使用DataFrame.query
过滤size
介于size_min
和size_max
之间的行。但这会导致行爆炸,因此在您的示例中为
12000*5000 = 60 000 000
行。方法二:
pd.IntervalIndex
:如果没有重叠的范围,那么如果我们将 Dataframe
df_types
中的size_min 16
更改为15
,我们可以使用此方法,这不会导致行爆炸。4dc9hkyq2#
这比Erfan的解决方案要长得多;我之所以提供这种方法,是因为我相信它可以帮助避免合并导致的行数增加。
这是在SQL查询中查找与where子句匹配的cond1和cond2。下一步压缩这两个列表并查找元素的索引(True,True)...获得的索引与df_types的索引等效。根据索引连接从df_types提取的所有 Dataframe ,并再次连接到df_products。
应该有比这更好的办法;然而,我确实相信SQL在这方面做得更好。
更新
随着时间的推移,希望我们能做得更好,我又试了一次,将事务转移到vanilla Python中,然后将最终结果返回给Pandas:
获取Pandas Dataframe :
注意,最后一项'G'返回两行,因为它基于条件匹配这两行。
2023年更新
将来自pyjanitor的conditional_join用于非对等连接: