设置
我有2个熊猫数据框:
df_ads
:每一行包含一个拆下的房屋广告的信息,df_ads['ad_post_code']
包含广告的荷兰邮政编码。df_mapping
:邮政编码与NUTS3地区之间的映射我需要将每个广告的邮政编码映射到其NUTS3区域。
数据框
df_ads['ad_post_code']
看起来像
0 1567 JA
1 3893 GB
2 5091 BE
3 1087 MB
4 7905 GW
5 5121 ZH
其中len(df_ads['ad_post_code']) = 85447
。
df_mapping
外观
CODE NUTS_3
0 1011 NL326
1 1012 NL326
2 1013 NL326
3 1014 NL326
4 1015 NL326
5 1016 NL326
其中len(df_mapping) = 4074
,df_mapping['CODE']
显示荷兰邮政编码的前4个字符,而df_mapping['NUTS_3']
是邮政编码的NUTS3区域。
换句话说,邮政编码1011
位于NUTS3区域NL326
中。
问题
我已经做了一些简单的循环,将df_ads
中的广告映射到NUTS3区域。但是,我似乎无法编写正确的循环设置。
nuts3_map = []
# insert postal codes into list
for i in range(0,len(df_ads)):
postal_code_ad = df_ads['ad_post_code'].iloc[i].split()[0]
for j in range(0,len(df_mapping)):
postal_code_map = str(df_mapping['CODE'].iloc[j])
# check if postal code match
if postal_code_ad == postal_code_map:
nuts3_map.append(df_mapping['NUTS_3'].iloc[j])
break
continue
运行此命令会得到len(nuts3_map) = 85353
,而len(df_ads) = 85448
,这样df_ads['nuts3'] = nuts3
就会得到ValueError: Length of values does not match length of index
。
double for循环是最快的方法吗?如果是这样,如何解决我的for循环,使其一切正常?
答案 0 :(得分:0)
我首先要在df_ads
中创建另一列:
# If `df_mapping['CODE']` is `int`
df_ads['CODE'] = df_ads['ad_post_code'].apply(lambda x: int(x[:4]))
# If `df_mapping['CODE']` is `str`
# df_ads['CODE'] = df_ads['ad_post_code'].apply(lambda x: x[:4])
然后,我将使用DataFrame.merge
对两个数据帧进行内部合并:
df_ads.merge(df_mapping, left_on='CODE', right_on='CODE', how='inner')
我可以自由地修改您的数据以产生可行的示例:
# df_ads['ad_post_code']
0 1567 JA
1 3893 GB
2 5091 BE
3 1087 MB
4 7905 GW
5 5121 ZH
6 1011 XX
# df_mapping
CODE NUTS_3
0 1011 NL326
1 1012 NL326
2 1013 NL326
3 1014 NL326
4 1015 NL326
5 1016 NL326
6 1567 XSFDF
输出:
ad_post_code CODE NUTS_3
0 1567 JA 1567 XSFDF
1 1011 XX 1011 NL326
如果df_ads['CODE']
中的每个代码都在df_mapping['CODE']
中存在,那么您应该获得正确的输出。
编辑
如果您想知道df_mapping
中的列表是否完整,可以执行以下操作:
df_ads.loc [np.logical_not(df_ads ['CODE']。isin(df_mapping ['CODE']))]
缺少数据:
ad_post_code CODE
id
1 3893 GB 3893
2 5091 BE 5091
3 1087 MB 1087
4 7905 GW 7905
5 5121 ZH 5121