Pandas 根据以前的数据填写数据框
我正在与一家零售商合作一个项目,我们希望清理一些数据以用于报告目的。 该零售商有多家店铺,每周店铺的工作人员都会扫描不同显示器上的不同商品(他们会先扫描显示器,让我们知道他们谈论的是哪个显示器)。此外,他们只扫描在那一周内改变的显示,如果显示没有改变,那么我们假设它保持不变 现在,我们正在处理2个数据帧: 层次结构数据帧示例: 该表基本上为每家商店的每个端盖(显示器)提供了第1到52周的时间。假设该公司只有2家门店,每家门店有3个端盖。此外,不同的商店可能有不同的终端上限代码,但这对我们的目的不重要(我不认为) 接下来,我们有一个历史文件,其中包含用于更新端盖的实际更改Pandas 根据以前的数据填写数据框,pandas,dataframe,Pandas,Dataframe,我正在与一家零售商合作一个项目,我们希望清理一些数据以用于报告目的。 该零售商有多家店铺,每周店铺的工作人员都会扫描不同显示器上的不同商品(他们会先扫描显示器,让我们知道他们谈论的是哪个显示器)。此外,他们只扫描在那一周内改变的显示,如果显示没有改变,那么我们假设它保持不变 现在,我们正在处理2个数据帧: 层次结构数据帧示例: 该表基本上为每家商店的每个端盖(显示器)提供了第1到52周的时间。假设该公司只有2家门店,每家门店有3个端盖。此外,不同的商店可能有不同的终端上限代码,但这对我们的目的不
Week Store End Cap UPC
0 1 1 A 123456
1 1 1 B 789456
2 1 1 B 546879
3 1 1 C 423156
4 1 2 A 231567
5 1 2 B 456123
6 1 2 D 689741
7 2 1 A 321654
8 2 1 C 852634
9 2 1 C 979541
10 2 2 A 132645
11 2 2 B 787878
12 2 2 D 615432
要合并我使用的两个数据帧:
merged_df = pd.merge(hierarchy, hist, how='left', left_on=['Week','Store', 'End Cap'], right_on = ['Week','Store', 'End Cap'])
这给了我:
Week Store End Cap UPC
0 1 1 A 123456.0
1 1 1 B 789456.0
2 1 1 B 546879.0
3 1 1 C 423156.0
4 1 2 A 231567.0
5 1 2 B 456123.0
6 1 2 D 689741.0
7 2 1 A 321654.0
8 2 1 B NaN
9 2 1 C 852634.0
10 2 1 C 979541.0
11 2 2 A 132645.0
12 2 2 B 787878.0
13 2 2 D 615432.0
除了一个显示NAN的实例。第2周的门店1端盖2未发生变化,因此未进行扫描。所以它没有出现在历史数据框中。在本例中,我希望查看在该商店扫描的该端盖的最新项目(请参见历史数据框的第2行和第3行)。从技术上讲,去年第52周也可以对其进行扫描,但我只想用最新信息填写NAN,以表明其没有改变。我该怎么做呢
所需的输出如下所示:
Week Store End Cap UPC
0 1 1 A 123456.0
1 1 1 B 789456.0
2 1 1 B 546879.0
3 1 1 C 423156.0
4 1 2 A 231567.0
5 1 2 B 456123.0
6 1 2 D 689741.0
7 2 1 A 321654.0
8 2 1 B 789456.0
9 2 1 B 546879.0
10 2 1 C 852634.0
11 2 1 C 979541.0
12 2 2 A 132645.0
13 2 2 B 787878.0
14 2 2 D 615432.0
谢谢大家!
编辑:
除此之外,我还尝试对数据进行排序,然后向前填充,这只部分解决了我的问题:
sorted_df = merged_df.sort_values(['End Cap', 'Store'], ascending=[True, True])
Week Store End Cap UPC
0 1 1 A 123456.0
7 2 1 A 321654.0
4 1 2 A 231567.0
11 2 2 A 132645.0
1 1 1 B 789456.0
2 1 1 B 546879.0
8 2 1 B NaN
5 1 2 B 456123.0
12 2 2 B 787878.0
3 1 1 C 423156.0
9 2 1 C 852634.0
10 2 1 C 979541.0
6 1 2 D 689741.0
13 2 2 D 615432.0
sorted_filled = sorted_df.fillna(method='ffill')
给我:
Week Store End Cap UPC
0 1 1 A 123456.0
7 2 1 A 321654.0
4 1 2 A 231567.0
11 2 2 A 132645.0
1 1 1 B 789456.0
2 1 1 B 546879.0
8 2 1 B 546879.0
5 1 2 B 456123.0
12 2 2 B 787878.0
3 1 1 C 423156.0
9 2 1 C 852634.0
10 2 1 C 979541.0
6 1 2 D 689741.0
13 2 2 D 615432.0
该输出确实将546879添加到第2周store1端盖B,但没有添加我也需要的789456。我需要它来添加另一个具有该值的行。您可以尝试以下方法:
#不带Nan值的新df
df1=merged_df[~merged_df[“name”].isna()]
#仅具有Nan值的新df
df2=merged_df[merged_df[“name”].isna()]
#上周定
df2[“周”]=df2[“周”]-1
#对于df2中的每个W/S/EC,获取df1中相应的UPC值
#并将新行(移回本周)附加到df1
对于df2中的周[“周”]。值:
对于df2中的存储[“存储”]。值:
对于df2[“Enc cap”]中的cap。值:
遮罩=(
(df1[“周”]==周)
&(df1[“存储”]==存储)
&(df1[“端盖”]==端盖)
)
upc=df1.loc[掩码,“upc”]。项()
行=[第1周,商店,上限,upc]
df1.loc[len(df1)]=行
排序的\ u df=df1.排序\ u值(按=[“周”、“存储”、“结束上限”])
您也可以这样做,创建一个帮助器列来处理每个门店/周/期末的重复UPC
idxcols=['Week', 'Store', 'End Cap']
hist_idx = hist.set_index(idxcols + [hist.groupby(idxcols).cumcount()])
hier_idx = hierarchy.set_index(idxcols+[hierarchy.groupby(idxcols).cumcount()])
hier_idx.join(hist_idx, how='right')\
.unstack('Week')\
.ffill(axis=1)\
.stack('Week')\
.reorder_levels([3,0,1,2])\
.sort_index()\
.reset_index()\
.drop('level_3', axis=1)
输出:
Week Store End Cap UPC
0 1 1 A 123456.0
1 1 1 B 789456.0
2 1 1 B 546879.0
3 1 1 C 423156.0
4 1 2 A 231567.0
5 1 2 B 456123.0
6 1 2 D 689741.0
7 2 1 A 321654.0
8 2 1 B 789456.0
9 2 1 B 546879.0
10 2 1 C 852634.0
11 2 1 C 979541.0
12 2 2 A 132645.0
13 2 2 B 787878.0
14 2 2 D 615432.0
我不明白…你想用UPC
789456
或546879
填充NaN
吗?嗨,你能给你的问题添加一个所需输出的例子吗?嗨@AndrejKesely我添加了一个所需输出。谢谢你看。基本上,如果本周未扫描end cap,请用end cap最近的扫描结果填充它。Hi@Laurent I添加了所需的输出。谢谢你看。基本上,如果本周未扫描端盖,请使用端盖hadOk的最新扫描填充它,但正如@Andrej Kesely所指出的,为什么要用789456而不是546879填充Nan值?如何在历史数据框中区分重复的Week+Store+EndCap行(例如1/1/B)?感谢您的回答和所有努力Laurent!我在运行它时遇到了一个问题,但您的逻辑似乎与最终运行的逻辑非常相似。非常有效,谢谢!
Week Store End Cap UPC
0 1 1 A 123456.0
1 1 1 B 789456.0
2 1 1 B 546879.0
3 1 1 C 423156.0
4 1 2 A 231567.0
5 1 2 B 456123.0
6 1 2 D 689741.0
7 2 1 A 321654.0
8 2 1 B 789456.0
9 2 1 B 546879.0
10 2 1 C 852634.0
11 2 1 C 979541.0
12 2 2 A 132645.0
13 2 2 B 787878.0
14 2 2 D 615432.0