在 Pandas 中查找特定列

问题描述 投票:0回答:1

我在 Pandas 中使用合并功能时遇到一些困难。我正在为此寻找某种 Vlookup 公式。但是,我无法解决我的问题。

我的数据很大,由于保密原因无法在这里分享。不过,我尝试在这里得出类似的数据。

旧代码 新代码 姓名 发票日期
1001011 不适用 芝士蛋糕 2021/02/02
1001012 不适用 咖啡 2021/03/05
1001011 不适用 芝士蛋糕 2021年5月30日
不适用 2002093 茉莉花茶 21/08/2021
不适用 2002042 饼干 2021 年 12 月 31 日
不适用 2002080 咖啡 2022年9月1日
不适用 2002093 茉莉花茶 2022年5月5日
不适用 2002058 芝士蛋糕 2022年7月6日

我想在上面的表格中输入“成本”列。但是,费用根据发票日期而异(另请注意产品代码的更改)。我们有 2 个成本表。 2021 年:

旧代码 新代码 姓名 21 年 1 月 2 月 21 日 3 月 21 日 4 月 21 日 5月21日 6 月 21 日 7 月 21 日 8 月 21 日 9 月 21 日 10 月 21 日 11 月 21 日 12 月 21 日
1001011 2002058 芝士蛋糕 50 51 50 53 54 52 55 53 50 52 53 53
1001012 2002080 咖啡 5 6 5 6 6 5 7 5 6 5 6 6
1001015 2002093 茉莉花茶 4 3 3 4 4 3 5 3 3 3 3 4
1001020 2002042 饼干 20 20 21 20 22 20 21 20 22 20 21 22

2022 年:

旧代码 新代码 姓名 1 月 22 日 2 月 22 日 3 月 22 日 4 月 22 日 5月22日 6 月 22 日 7 月 22 日 8 月 22 日 9 月 22 日 10 月 22 日 11 月 22 日 12 月 22 日
1001011 2002058 芝士蛋糕 52 52 55 55 56 52 不适用 不适用 不适用 不适用 不适用 不适用
1001012 2002080 咖啡 5 6 5 6 6 6.5 不适用 不适用 不适用 不适用 不适用 不适用
1001015 2002093 茉莉花茶 4 3 3 5 5 5.5 不适用 不适用 不适用 不适用 不适用 不适用
1001020 2002042 饼干 22 22 23 23 23.5 23 不适用 不适用 不适用 不适用 不适用 不适用

所以基本上,我希望在我的第一个数据框中包含我的成本列,以反映不同年份和不同月份的正确成本计算。

示例:

发票日期成本核算 03/05/2021 = May_2021

python pandas dataframe merge vlookup
1个回答
0
投票

合并时需要两边都有月份和代码,所以:

  1. 在发票数据框中创建与成本表一致的年月列
  2. 合并两个成本表
  3. 分别与新代码和旧代码合并


import pandas as pd
import io
import datetime

invoice_data_text = '''Old Code New Code    Name    Invoice Date
1001011 NA  Cheese Cake 02/02/2021
1001012 NA  Coffee  03/05/2021
1001011 NA  Cheese Cake 30/05/2021
NA  2002093 Jasmine Tea 21/08/2021
NA  2002042 Cookies 31/12/2021
NA  2002080 Coffee  09/01/2022
NA  2002093 Jasmine Tea 05/05/2022
NA  2002058 Cheese Cake 07/06/2022
'''

cost_2021_text = '''
Old Code    New Code    Name    Jan-21  Feb-21  Mar-21  Apr-21  May-21  June-21 Jul-21  Aug-21  Sep-21  Oct-21  Nov-21  Dec-21
1001011 2002058 Cheese Cake 50  51  50  53  54  52  55  53  50  52  53  53
1001012 2002080 Coffee  5   6   5   6   6   5   7   5   6   5   6   6
1001015 2002093 Jasmine Tea 4   3   3   4   4   3   5   3   3   3   3   4
1001020 2002042 Cookies 20  20  21  20  22  20  21  20  22  20  21  22
'''

cost_2022_text = '''
Old Code    New Code    Name    Jan-22  Feb-22  Mar-22  Apr-22  May-22  June-22 Jul-22  Aug-22  Sep-22  Oct-22  Nov-22  Dec-22
1001011 2002058 Cheese Cake 52  52  55  55  56  52  NA  NA  NA  NA  NA  NA
1001012 2002080 Coffee  5   6   5   6   6   6.5 NA  NA  NA  NA  NA  NA
1001015 2002093 Jasmine Tea 4   3   3   5   5   5.5 NA  NA  NA  NA  NA  NA
1001020 2002042 Cookies 22  22  23  23  23.5    23  NA  NA  NA  NA  NA  NA
'''

# Prepare
invoice_df = pd.read_csv(io.StringIO(invoice_data_text),sep="\t",parse_dates=["Invoice Date"])
cost21 = pd.read_csv(io.StringIO(cost_2021_text),sep='\t')
cost22 =  pd.read_csv(io.StringIO(cost_2022_text),sep='\t')

# Create Month column for merging
invoice_df["Month"] = invoice_df["Invoice Date"].map(lambda x:datetime.datetime.strftime(x,"%b-%y"))

# Combine two cost tables
cost21_stack = cost21.set_index(list(cost21.columns[:3])).stack().reset_index(name="Cost")
cost22_stack = cost22.set_index(list(cost22.columns[:3])).stack().reset_index(name="Cost")
cost_table = pd.concat([cost21_stack,cost22_stack]).rename({"level_3":"Month"},axis=1)

# Merge with new code and old code respectively
old_code_result = pd.merge(invoice_df[pd.isna(invoice_df["Old Code"]) == False], cost_table[["Old Code","Month","Cost"]], on=["Old Code","Month"] ,how="left")
new_code_result = pd.merge(invoice_df[pd.isna(invoice_df["New Code"]) == False], cost_table[["New Code","Month","Cost"]], on=["New Code","Month"] ,how="left")

# Combine result
pd.concat([old_code_result,new_code_result])
    
© www.soinside.com 2019 - 2024. All rights reserved.