遍历数据框并根据字典条件进行更新
Iterating through dataframe and updating based on dictionary conditions
我想遍历数据框,如果列 ITEM CODE 包含字典键,我想检查同一行是否包含字典值[0](元组中的第一个位置),如果包含 I想要将字典值1(元组中的第二个位置)插入另一个名为 SKU
的列
数据框:#df3 = df2.append(df1)
catp = {"2755":(('24','002'),('25','003'),('26','003'),('27','004'),('28','005'),('29','006'),('30','007'),('31','008'),
('32','009'),('32','010'),('33','011'),('34','012'),('35','013'),('36','014')),
"2513":(('38','002'),('40','003'),('42','004'),('44','005'),('46','006'),('48','007'),('50','008'),('52','009'),
('54','010'))}
for i, row in df3.iterrows():
if catp.key() in df3['ITEM CODE'][i] and catp.value()[0] in df3['TG'][i]:
codmarime = catp.value()[1]
df3['SKU'][i] = '20'+df3['ITEM CODE'][i]+[i]+codmarime
else:
df3['SKU'][i] = '20'+df3['ITEM CODE'][i]+'???'
如果找到 2755 和 24 SKU = '202755638002'
如果找到 2513 和 44 SKU = '202513123005'
输出xlsx
我无法正确理解问题,只是更正我在您的代码中看到的错误:
if catp.key() in df3['ITEM CODE'][i] and catp.value()[0] in df3['TG'][i]:
这是不正确的。
如果我理解最终目标,我正在采取不同的方法应该行得通
for key in catp.keys():
xdf = df3.loc[(df3['SKU'].astype(str).contains(key)) & (df3['SKU'].astype(str).contains(catp[key][0])]
if len(xdf)>0:
for i, row in xdf.iterrows():
codmarime = catp[key][1]
df3.at[i,'SKU'] = '20'+row['ITEM CODE'][i]+[i]+codmarime
由于您未能提供文本数据来至少创建 DataFrame 的一个片段,
我从你的图片中复制了 3 行,创建了我的测试 DataFrame:
df3 = pd.DataFrame(data=[
[ '1513452', 'AVRO D2', '685', 'BLACK/BLACK/ANTRACITE', '24', 929.95, '8052644627565' ],
[ '2513452', 'AVRO D2', '685', 'BLACK/BLACK/ANTRACITE', '21', 929.95, '8052644627565' ],
[ '2755126', 'AMELIA', 'Y17', 'DARK-DENIM', '24', 179.95, '8052644627565' ]],
columns=[ 'ITEM CODE', 'ITEM', 'COLOR', 'COLOR CODE', 'TG', 'PRICE', 'EAN' ])
详情:
- 第一行不包含
ITEM CODE
列中的任何 catp
个键。
- 第二行:
ITEM CODE
包含您的代码之一 (2513) 但对于 TG
2513
键下没有保存的列包含第一个元素 == 21.
- 第三行:
ITEM CODE
包含您的代码之一(2755),TG
== 24
在 2755
下保存的元组中有一个 == 24.
然后我们必须定义几个辅助函数:
def findContainedCodeAndVal(dct, str):
for eachKey in dct.keys():
if str.find(eachKey) >= 0:
return (eachKey, dct[eachKey])
else:
return (None, None)
此函数尝试在 dct
中查找包含在 str
中的键。
它 returns 一个包含从 dct
.
中找到的键和关联值的二元组
def find2ndElem(tuples, str):
for tpl in tuples:
if tpl[0] == str:
return tpl[1]
else:
return ''
此函数检查 tuples
中的每个元组是否是其第一个元素
== str
和 returns 这个元组的第二个元素。
最后定义的函数是应用于每一行的函数
来自你的数据框。它 returns 要保存在 SKU
列中的值:
def fn(row):
ind = row.name # Read row index
iCode = row['ITEM CODE']
k, val = findContainedCodeAndVal(catp, iCode)
codmarime = ''
if k:
tg = row.TG
codmarime = find2ndElem(val, tg)
if codmarime == '':
codmarime = '???'
return f'20/{iCode}/{ind}/{codmarime}'
请注意,它使用您的 catp
词典。
为了演示,我在返回值中额外引入了
斜线,分隔相邻的部分。在目标版本中删除它们。
最后要做的是计算 DataFrame 的 SKU
列,
将 fn
函数应用于 df3
的每一行并将结果保存在
SKU
列:
df3['SKU'] = df3.apply(fn, axis=1)
当您打印 DataFrame(包含我的测试数据)时,SKU
列将
包含:
20/1513452/0/???
20/2513452/1/???
20/2755126/2/002
我想遍历数据框,如果列 ITEM CODE 包含字典键,我想检查同一行是否包含字典值[0](元组中的第一个位置),如果包含 I想要将字典值1(元组中的第二个位置)插入另一个名为 SKU
的列数据框:#df3 = df2.append(df1)
catp = {"2755":(('24','002'),('25','003'),('26','003'),('27','004'),('28','005'),('29','006'),('30','007'),('31','008'),
('32','009'),('32','010'),('33','011'),('34','012'),('35','013'),('36','014')),
"2513":(('38','002'),('40','003'),('42','004'),('44','005'),('46','006'),('48','007'),('50','008'),('52','009'),
('54','010'))}
for i, row in df3.iterrows():
if catp.key() in df3['ITEM CODE'][i] and catp.value()[0] in df3['TG'][i]:
codmarime = catp.value()[1]
df3['SKU'][i] = '20'+df3['ITEM CODE'][i]+[i]+codmarime
else:
df3['SKU'][i] = '20'+df3['ITEM CODE'][i]+'???'
如果找到 2755 和 24 SKU = '202755638002'
如果找到 2513 和 44 SKU = '202513123005'
输出xlsx
我无法正确理解问题,只是更正我在您的代码中看到的错误:
if catp.key() in df3['ITEM CODE'][i] and catp.value()[0] in df3['TG'][i]:
这是不正确的。
如果我理解最终目标,我正在采取不同的方法应该行得通
for key in catp.keys():
xdf = df3.loc[(df3['SKU'].astype(str).contains(key)) & (df3['SKU'].astype(str).contains(catp[key][0])]
if len(xdf)>0:
for i, row in xdf.iterrows():
codmarime = catp[key][1]
df3.at[i,'SKU'] = '20'+row['ITEM CODE'][i]+[i]+codmarime
由于您未能提供文本数据来至少创建 DataFrame 的一个片段, 我从你的图片中复制了 3 行,创建了我的测试 DataFrame:
df3 = pd.DataFrame(data=[
[ '1513452', 'AVRO D2', '685', 'BLACK/BLACK/ANTRACITE', '24', 929.95, '8052644627565' ],
[ '2513452', 'AVRO D2', '685', 'BLACK/BLACK/ANTRACITE', '21', 929.95, '8052644627565' ],
[ '2755126', 'AMELIA', 'Y17', 'DARK-DENIM', '24', 179.95, '8052644627565' ]],
columns=[ 'ITEM CODE', 'ITEM', 'COLOR', 'COLOR CODE', 'TG', 'PRICE', 'EAN' ])
详情:
- 第一行不包含
ITEM CODE
列中的任何catp
个键。 - 第二行:
ITEM CODE
包含您的代码之一 (2513) 但对于TG
2513
键下没有保存的列包含第一个元素 == 21. - 第三行:
ITEM CODE
包含您的代码之一(2755),TG
== 24 在2755
下保存的元组中有一个 == 24.
然后我们必须定义几个辅助函数:
def findContainedCodeAndVal(dct, str):
for eachKey in dct.keys():
if str.find(eachKey) >= 0:
return (eachKey, dct[eachKey])
else:
return (None, None)
此函数尝试在 dct
中查找包含在 str
中的键。
它 returns 一个包含从 dct
.
def find2ndElem(tuples, str):
for tpl in tuples:
if tpl[0] == str:
return tpl[1]
else:
return ''
此函数检查 tuples
中的每个元组是否是其第一个元素
== str
和 returns 这个元组的第二个元素。
最后定义的函数是应用于每一行的函数
来自你的数据框。它 returns 要保存在 SKU
列中的值:
def fn(row):
ind = row.name # Read row index
iCode = row['ITEM CODE']
k, val = findContainedCodeAndVal(catp, iCode)
codmarime = ''
if k:
tg = row.TG
codmarime = find2ndElem(val, tg)
if codmarime == '':
codmarime = '???'
return f'20/{iCode}/{ind}/{codmarime}'
请注意,它使用您的 catp
词典。
为了演示,我在返回值中额外引入了 斜线,分隔相邻的部分。在目标版本中删除它们。
最后要做的是计算 DataFrame 的 SKU
列,
将 fn
函数应用于 df3
的每一行并将结果保存在
SKU
列:
df3['SKU'] = df3.apply(fn, axis=1)
当您打印 DataFrame(包含我的测试数据)时,SKU
列将
包含:
20/1513452/0/???
20/2513452/1/???
20/2755126/2/002