使用向量化,我想根据第二列的值根据嵌套字典重新映射一列。在迭代逻辑中,我将遍历所有行;根据第二列中的值,我将从字典的第一级(也就是字典)中选择一个条目,据此映射值。
MWE
我有一个感兴趣的数据框,其中包含两列:country
和variable
:
df= pd.DataFrame({"country": ["AA", "BB", "AA", "AA", "BB", "AA"],
"variable": ["foo/tball", "palace", "bla", "car", "bla", "dog"]})
我还有一个嵌套的字典dct
(variable
中的值仅与country
结合使用是唯一的,因此我无法嵌套该字典)。 dct
包含df['variable']
中的条目字符串及其子字符串:
dct = {"AA": {'foo': 'NEWFOO', # substring of 'foo/tball'
'bla' : 'NEWBLA',
'cart': 'this value is not in the dataframe'}, # sic! -- not substring of any entry
"BB": {'pal': 'NEWPAL', # substring of palace
'bla': 'DIFFERENT_NEWBLA'},
"CC": {"this": "'CC' dictionary can be ignored"}}
我现在想按照以下规则根据df['variable']
映射dct[df['country']]
的条目:
df['variable']
中条目的子字符串(例如'foo'
中的dct['AA']
:请根据字典替换条目'dog'
),请替换为一些预定义的值(此处为_some_flag_value_
)'country'
列(例如dct["CC"]
)或'variable'
列(例如'cart'
中的dct['AA']
都不匹配的条目)。所需的输出应如下所示:
out = pd.DataFrame({"country": ["AA", "BB", "AA", "AA", "BB", "AA"],
"variable": ["NEWFOO", "NEWPAL", "NEWBLA", "_some_flag_value_",
"DIFFERENT_NEWBLA", "_some_flag_value_"]})
我尝试将df.mapapply()
与lambda
的几种组合一起使用都无济于事-有人可以指出我正确的方向吗?提前谢谢。
答案 0 :(得分:1)
您可以使用pd.Series.str.cat
使用自定义分隔符将两列连接在一起,然后使用pd.Series.map
def f(x):
c, v = x.split('-')
d = dct.get(c)
for k,val in d.items():
if k in v:
return val
else:
return '_some_flag_value_'
df.assign(variable = df['country'].str.cat(df['variable'],sep='-').map(f))
country variable
0 AA NEWFOO
1 BB NEWPAL
2 AA NEWBLA
3 AA _some_flag_value_
4 BB DIFFERENT_NEWBLA
5 AA _some_flag_value_
或使用df.apply
1
def f(x):
c, v = x
d = dct.get(c)
for k,val in d.items():
if k in v:
return val
else:
return '_some_flag_value_'
df.assign(variable = df.apply(f,axis=1))
时间结果:
使用问题中给出的数据框进行基准测试。
In [84]: %timeit df.assign(variable = df['country'].str.cat(df['variable'],sep='-').map(f))
...:
694 µs ± 22.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [82]: %timeit df.assign(variable = df.apply(f,axis=1))
...:
915 µs ± 40.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1 df.apply
,因为它运行缓慢并且在引擎盖下循环。看看这个answer by cs95