Python 基于dict值分配给数据帧列

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

考虑以下数据帧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   {'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("'", '"'))}
)