LeetCode数据专题:1795. 每个产品在不同商店的价格
题目描述
表:Products
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| product_id | int |
| store1 | int |
| store2 | int |
| store3 | int |
+-------------+---------+
在 SQL 中,这张表的主键是 product_id(产品Id)。
每行存储了这一产品在不同商店 store1, store2, store3 的价格。
如果这一产品在商店里没有出售,则值将为 null。
请你重构 Products
表,查询每个产品在不同商店的价格,使得输出的格式变为(product_id, store, price)
。如果这一产品在商店里没有出售,则不输出这一行。
输出结果表中的 顺序不作要求 。
查询输出格式请参考下面示例。
示例 1:
输入:
Products table:
+------------+--------+--------+--------+
| product_id | store1 | store2 | store3 |
+------------+--------+--------+--------+
| 0 | 95 | 100 | 105 |
| 1 | 70 | null | 80 |
+------------+--------+--------+--------+
输出:
+------------+--------+-------+
| product_id | store | price |
+------------+--------+-------+
| 0 | store1 | 95 |
| 0 | store2 | 100 |
| 0 | store3 | 105 |
| 1 | store1 | 70 |
| 1 | store3 | 80 |
+------------+--------+-------+
解释:
产品 0 在 store1、store2、store3 的价格分别为 95、100、105。
产品 1 在 store1、store3 的价格分别为 70、80。在 store2 无法买到。
解题思路
我们可以使用动态的交叉连接(CROSS JOIN)来获取不同商店的组合。然后,使用条件语句和聚合函数来计算每个产品在不同商店的价格。
代码实现
MySQL 实现
- union
SELECT product_id, 'store1' AS store, store1 AS price
FROM Products
WHERE store1 IS NOT NULL
UNION
SELECT product_id, 'store2' AS store, store2 AS price
FROM Products
WHERE store2 IS NOT NULL
UNION
SELECT product_id, 'store3' AS store, store3 AS price
FROM Products
WHERE store3 IS NOT NULL
Pandas 实现
- union
def rearrange_products_table(products: pd. DataFrame ) -> pd. DataFrame :
a = products.loc[products['store1'].notna(), ['product_id', 'store1']]
a['store'] = "store1"
a.rename(columns={'store1':'price'}, inplace=True)
a = a[['product_id', 'store', 'price']]
b = products.loc[products['store2'].notna(), ['product_id', 'store2']]
b['store'] = "store2"
b.rename(columns={'store2':'price'}, inplace=True)
b = b[['product_id', 'store', 'price']]
c = products.loc[products['store3'].notna(), ['product_id', 'store3']]
c['store'] = "store3"
c.rename(columns={'store3':'price'}, inplace=True)
c = c[['product_id', 'store', 'price']]
answer = pd.concat([a, b, c])
return answer
- 透视
import pandas as pd
def rearrange_products_table(products: pd. DataFrame ) -> pd. DataFrame :
df = products.melt(
id_vars='product_id',
value_vars=['store1', 'store2', 'store3'],
var_name='store',
value_name='price')
df = df.dropna(axis=0)
return df
)
- 行列转换stack
import pandas as pd
def rearrange_products_table(products: pd.DataFrame) -> pd.DataFrame:
# set_index 会按照[product_id]进行分行(大行包小行)
df = products.set_index(['product_id']).stack()
# 与 set_index 对照看
df = df.reset_index()
# 重新命名
df.columns = ['product_id','store','price']
return df
- 已知输入:
| product_id | store1 | store2 | store3 |
| ---------- | ------ | ------ | ------ |
| 0 | 95 | 100 | 105 |
| 1 | 70 | null | 80 |
- 三次
df
的输出为:
product_id
0 store1 95
store2 100
store3 105
1 store1 70
store3 80
dtype: Int64
product_id level_1 0
0 0 store1 95
1 0 store2 100
2 0 store3 105
3 1 store1 70
4 1 store3 80
| product_id | store | price |
| ---------- | ------ | ----- |
| 0 | store1 | 95 |
| 0 | store2 | 100 |
| 0 | store3 | 105 |
| 1 | store1 | 70 |
| 1 | store3 | 80 |