Python 基于dict值分配给数据帧列
考虑以下数据帧df:Python 基于dict值分配给数据帧列,python,pandas,Python,Pandas,考虑以下数据帧df: Address City State Zip Code Query Result 0 55 W Waterloo Rd Akron OH 44319 {'field1': 'street_number', 'longname1': '55', 'field2': 'route', 'longname2': 'West Waterloo Road'} 1 1120 Hwy 20 Correctionville IA 51016
Address City State Zip Code Query Result
0 55 W Waterloo Rd Akron OH 44319 {'field1': 'street_number', 'longname1': '55', 'field2': 'route', 'longname2': 'West Waterloo Road'}
1 1120 Hwy 20 Correctionville IA 51016 {'field1': 'street_number', 'longname1': '1120', 'field2': 'route', 'longname2': 'U.S. 20'}
2 Hwy 12 and Bonito Dr Fort Defiance AZ 86504 {'field1': 'route', 'longname1': 'Indian Route 7', 'field2': 'locality', 'longname2': 'Fort Defiance'}
3 2661 County Hwy I Chippewa Falls WI 54729 {'field1': 'street_number', 'longname1': '2661', 'field2': 'route', 'longname2': 'County Highway I'}
4 301 US Rt 1 Ste A Scarborough ME 4074 {'field1': 'subpremise', 'longname1': 'a', 'field2': 'street_number', 'longname2': '301'}
5 500 W Broadway St Ste 5 Missoula MT 59807 {'field1': 'subpremise', 'longname1': '5', 'field2': 'street_number', 'longname2': '500'}
我想使用df['Query Result']中的dict填充df['street\u number']列,以便:
Address City State Zip Code Query Result street_number
0 55 W Waterloo Rd Akron OH 44319 {'field1': 'street_number', 'longname1': '55', 'field2': 'route', 'longname2': 'West Waterloo Road'} 55
1 1120 Hwy 20 Correctionville IA 51016 {'field1': 'street_number', 'longname1': '1120', 'field2': 'route', 'longname2': 'U.S. 20'} 1120
2 Hwy 12 and Bonito Dr Fort Defiance AZ 86504 {'field1': 'route', 'longname1': 'Indian Route 7', 'field2': 'locality', 'longname2': 'Fort Defiance'}
3 2661 County Hwy I Chippewa Falls WI 54729 {'field1': 'street_number', 'longname1': '2661', 'field2': 'route', 'longname2': 'County Highway I'} 2661
4 301 US Rt 1 Ste A Scarborough ME 4074 {'field1': 'subpremise', 'longname1': 'a', 'field2': 'street_number', 'longname2': '301'} 301
5 500 W Broadway St Ste 5 Missoula MT 59807 {'field1': 'subpremise', 'longname1': '5', 'field2': 'street_number', 'longname2': '500'} 500
有人能帮我理解怎么做吗?如果我需要更清楚地说明我的例子,请告诉我。我相信这就是您想要的: 我的示例数据帧(为了简洁起见,我省略了示例中的一些内容): 技巧似乎是访问dict,因为它嵌套在一个数组中:
df['Street Number'] = df['Query Result'].values[0]['longname1']
df
Address City State Zip Code Query Result Street Number
0 55 W Waterloo Rd Akron OH 44319 {'longname1': '55', 'field1': 'street_number'} 55
乍一看,街道号码似乎存储在
“longname1”
字段中。如果是这种情况,并且您的“查询结果”
列存储为dict
,则您可以轻松提取街道号码apply
:
df['street_number'] = df.apply(lambda x: x['Query Result'].get('longname1'), axis=1)
其中打印:
street_number Address City State Zip Code
0 55 55 W Waterloo Rd Akron OH 44319
1 1120 1120 Hwy 20 Correctionville IA 51016
2 Indian Route 7 Hwy 12 and Bonito Dr Fort Defiance AZ 86504
3 2661 2661 County Hwy I Chippewa Falls WI 54729
4 a 301 US Rt 1 Ste A Scarborough ME 4074
5 5 500 W Broadway St Ste 5 Missoula MT 59807
但是,这会产生错误的输出-“印度7号公路”
和“a”
看起来不像街道号码。因此,认为“longname1”
是关键的假设是有缺陷的
再看一下输入,似乎我们需要动态地找到街道编号的键。这是一个快速而肮脏的方法
搜索“查询结果”
中以单词“字段”
开头的所有键。然后,找到相应值为“street\u number”
的值。使用键末尾的数字作为索引
,并找到相应的“longname”
值:
def get_street_number(qr):
fields = [k for k in qr if k.startswith('field')]
street_number = [f for f in fields if qr[f] == 'street_number']
try:
# kind of a hacky way to get the number (index)
index = street_number[0].split('field')[1]
return qr['longname'+index]
except:
return None
df['street_number'] = df.apply(lambda x: get_street_number(x['Query Result']), axis=1)
(有很多方法可以做得更好,但它应该适合您的需要。)
示例数据的输出:
>>> print(df[['street_number', 'Address', 'City', 'State', 'Zip Code']])
street_number Address City State Zip Code
0 55 55 W Waterloo Rd Akron OH 44319
1 1120 1120 Hwy 20 Correctionville IA 51016
2 None Hwy 12 and Bonito Dr Fort Defiance AZ 86504
3 2661 2661 County Hwy I Chippewa Falls WI 54729
4 301 301 US Rt 1 Ste A Scarborough ME 4074
5 500 500 W Broadway St Ste 5 Missoula MT 59807
这与您提供的示例相匹配
更新:
如果您的查询结果
存储为字符串
,则可以使用json.loads()
将其转换为dict
:
或者,如果您正在读取文件,则可以使用read\u csv()
中的converters
选项执行读取时的转换:
filename = 'path/to/file'
df = pd.read_csv(
filename,
converters={'Query Result': lambda x: json.loads(x.replace("'", '"'))}
)
太棒了,非常感谢你。一件令人好奇的事:为什么是兰姆达?如果我运行df['street\u number']=df['Query Result'],我似乎得到了相同的输出。apply(get\u street\u number)您的方式是相同的。我使用了
lambda
,因为我在整个数据帧上调用了apply
,我只想将一个dict
列传递给函数。
import json
df['Query Result'] = df.apply(
lambda x: json.loads(x['Query Result'].replace("'", '"')), axis=1
)
filename = 'path/to/file'
df = pd.read_csv(
filename,
converters={'Query Result': lambda x: json.loads(x.replace("'", '"'))}
)