我有一个像下面这样的数据框架:
df = pd.DataFrame({'id' : [1,2,3],
'attributes' : [{'dd' : True, 'budget' : '35k'}, {'dd' : True, 'budget' : '25k'}, {'dd' : True, 'budget' : '40k'}],
'prod.attributes' : [{'img' : 'img1.url', 'name' : 'millennials'}, {'img' : 'img2.url', 'name' : 'single'}, {'img' : 'img3.url', 'name' : 'married'}]})
df
id attributes prod.attributes
0 1 {'dd': True, 'budget': '35k'} {'img': 'img1.url', 'name': 'millennials'}
1 2 {'dd': True, 'budget': '25k'} {'img': 'img2.url', 'name': 'single'}
2 3 {'dd': True, 'budget': '40k'} {'img': 'img3.url', 'name': 'married'}
我有多个这样的列,其中我需要将所有以attributes
为后缀的列与实际的attributes
列附加在一起,如下所示:
op = pd.DataFrame({'id' : [1,2,3],
'attributes' : [{'dd' : True, 'budget' : '35k', 'prod' : {'img' : 'img1.url', 'name' : 'millennials'}},
{'dd' : True, 'budget' : '25k', 'prod' : {'img' : 'img2.url', 'name' : 'single'}},
{'dd' : True, 'budget' : '40', 'prod' : {'img' : 'img3.url', 'name' : 'married'}}]})
op
id attributes
0 1 {'dd': True, 'budget': '35k', 'prod': {'img': 'img1.url', 'name': 'millennials'}}
1 2 {'dd': True, 'budget': '25k', 'prod': {'img': 'img2.url', 'name': 'single'}}
2 3 {'dd': True, 'budget': '40', 'prod': {'img': 'img3.url', 'name': 'married'}}
我试着:
df['attributes'].apply(lambda x : x.update({'audience' : df['prod.attributes']}))
但是我得到了所有的None
。有人能帮我一下吗?
比apply
更有效,使用循环并就地更新字典:
for d1, d2 in zip(df['attributes'], df['prod.attributes']):
d1['prod'] = d2
如果要删除原始列,请使用pop
:
for d1, d2 in zip(df['attributes'], df.pop('prod.attributes')):
d1['prod'] = d2
更新dataframe:
id attributes
0 1 {'dd': True, 'budget': '35k', 'prod': {'img': 'img1.url', 'name': 'millennials'}}
1 2 {'dd': True, 'budget': '25k', 'prod': {'img': 'img2.url', 'name': 'single'}}
2 3 {'dd': True, 'budget': '40k', 'prod': {'img': 'img3.url', 'name': 'married'}}
计时df = pd.concat([df]*10000, ignore_index=True)
%%timeit
for d1, d2 in zip(df['attributes'], df['prod.attributes']):
d1['prod'] = d2
3.49 ms ± 137 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
df['attributes'] = [{**a, **{'prod' : b}}
for a, b in zip(df['attributes'], df['prod.attributes'])]
11.3 ms ± 384 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
df.apply(lambda r: {**r['attributes'], **{'prod': r['prod.attributes']}}, axis=1)
173 ms ± 7.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
使用**
在列表推导中合并两个字典,DataFrame.pop
用于在使用:
df['attributes'] = [{**a, **{'prod' : b}}
for a, b in zip(df['attributes'], df.pop('prod.attributes'))]
print (df)
id attributes
0 1 {'dd': True, 'budget': '35k', 'prod': {'img': ...
1 2 {'dd': True, 'budget': '25k', 'prod': {'img': ...
2 3 {'dd': True, 'budget': '40k', 'prod': {'img': ...