Python 使用pandas在单独的列中获取具有相同值组合的行
我第一次尝试执行实体匹配,希望先“消除”明显的匹配,这样我就可以集中精力处理模糊的情况。我有一个包含近60万条关于衣服信息的数据集 我需要的是相同id、颜色和尺寸的供应商的所有不同价格 以下是一个例子:Python 使用pandas在单独的列中获取具有相同值组合的行,python,pandas,group-by,pandas-groupby,Python,Pandas,Group By,Pandas Groupby,我第一次尝试执行实体匹配,希望先“消除”明显的匹配,这样我就可以集中精力处理模糊的情况。我有一个包含近60万条关于衣服信息的数据集 我需要的是相同id、颜色和尺寸的供应商的所有不同价格 以下是一个例子: df = pd.DataFrame([{'product_id': 1, 'price': 10, 'supplier': 'A', 'color': "red", "size": "xl"},
df = pd.DataFrame([{'product_id': 1, 'price': 10, 'supplier': 'A', 'color': "red", "size": "xl"},
{'product_id': 2, 'price': 7, 'supplier': 'A', 'color': "blue", "size": "m"},
{'product_id': 2, 'price': 7, 'supplier': 'B', 'color': "blue", "size": "m"},
{'product_id': 1, 'price': 11, 'supplier': 'C', 'color': "red", "size": "xl"},
{'product_id': 3, 'price': 2, 'supplier': 'C', 'color': "red", "size": "s"},
{'product_id': 1, 'price': 3, 'supplier': 'A', 'color': "blue", "size": "XL"}]) #EDIT: added
这看起来像:
product_id price supplier color size
0 1 10 A red xl
1 2 7 A blue m
2 2 7 B blue m
3 1 11 C red xl
4 3 2 C red s
EDIT:
5 1 3 A blue xl
编辑备注:旧示例遗漏了一个关键方面:有些产品具有相同的产品id,但可以有多种颜色变化。设想产品1是一件standart白色T恤,我可以从多家供应商处订购不同尺寸和颜色的T恤。我还意识到我不需要供应商,见下文:
但我需要的是:
product_id color size price_a price_b price_c
0 1 red xl 10 - 11
1 1 blue xl 3 - -
2 2 blue m 7 7 -
3 3 red s - - 2
我知道我必须根据“产品id”、“颜色”和“大小”以及聚合函数进行分组。但是我不知道怎样才能让熊猫创建新的栏目price_a、price_b和price_c
我觉得这应该很简单,但我不能让它工作。
非常感谢您的帮助 我的想法是两个连接两个数据帧-一个没有副本的数据帧和每种类型都有价格的数据帧。我相信这可以通过使用较少的行来实现,但我将为您提供我的解决方案,因为没有其他解决方案:
pd.concat([
(
df.drop_duplicates(subset=['product_id', 'color', 'size'], keep='first')
.drop(columns='price')
.reset_index(drop=True)
)
,
(
df.groupby(['product_id', 'supplier'])['price']
.apply(lambda x: list(x)[0])
.to_frame()
.unstack()
.droplevel(0, axis=1)
.reset_index()
.drop('product_id', axis=1)
.rename(columns={'A': 'price_a', 'B': 'price_b', 'C': 'price_c'})
)
],
axis=1
).fillna('-')
输出:
product_id supplier color size price_a price_b price_c
0 1 A red xl 10.0 - 11.0
1 2 A blue m 7.0 7.0 -
2 3 C red s - - 2.0
以下步骤像魔术一样实现了输出:
groupby()
将w.r.tproduct\u id
和color
分组,并获取第一项颜色、大小以及价格和供应商的价值清单pd.Series.explode()
DatFrame.Pivot()
透视表<代码>产品id和颜色
作为索引,供应商
作为列,价格
作为值pd.concat()
将数据透视表与初始表合并,并使用DataFrame.drop()
干杯,非常感谢你的回答!它适用于给定的示例。我意识到,我忘记了示例数据集中的一个重要示例(请参见问题中的上述编辑)。很遗憾,对于新条目,您的代码没有返回正确的结果。你知道如何解决这个问题吗?干杯,非常感谢你的回答!不幸的是,另一个答案也是如此……它适用于给定的示例。我意识到,我忘记了示例数据集中的一个重要示例(请参见问题中的上述编辑)。很遗憾,对于新条目,您的代码没有返回正确的结果。你知道怎么解决这个问题吗?我已经更新了答案。分组需要基于
产品id
和颜色
立即生效!非常感谢!(除了行“out.drop(columns=[“product_id”,“color”],inplace=True)”必须注释掉,因为out此时不存在。)感谢您的帮助!
df = df.groupby(['product_id','color']).agg({'size':'first','price':list,'supplier':list}).reset_index()
price_details = df.set_index(['product_id',"color","size"]).apply(pd.Series.explode).reset_index()
price_details =pd.pivot_table(price_details,index=["product_id","color"], columns="supplier", values="price",aggfunc= 'first').add_prefix("price_").fillna("-").reset_index()
out = pd.concat([df,price_details],axis=1)
out.drop(columns = ["price"], inplace=True)
out.supplier = out.supplier.apply(lambda x: x[0])
print(out)
product_id color size supplier product_id color price_A price_B price_C
0 1 blue XL A 1 blue 3 - -
1 1 red xl A 1 red 10 - 11
2 2 blue m A 2 blue 7 7 -
3 3 red s C 3 red - - 2