根据字典值

时间:2018-01-19 19:37:57

标签: 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   {'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 ['查询结果']中使用dict填充df [' street_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

有人可以帮我解决这个问题吗?如果我需要让我的例子更清楚,请告诉我。

2 个答案:

答案 0 :(得分:2)

乍一看,似乎街道号码存储在"longname1"字段中。如果是这种情况,并且您的"Query Result"列已存储为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

然而,这会产生错误的输出 - "Indian Route 7""a"看起来不像街道号码。因此,假设"longname1"是关键是有缺陷的。

再看一下输入,似乎我们需要动态找到街道号码的关键字。这是一种快速而肮脏的方法。

搜索"Query Result"中以"field"开头的所有密钥。然后,对于那些,找到对应值为"street_number"的那个。将密钥末尾的数字用作index,并找到相应的"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

与您提供的示例匹配。

<强>更新

如果您的Query Result存储为string,则可以使用dict将其转换为json.loads()

import json
df['Query Result'] = df.apply(
    lambda x: json.loads(x['Query Result'].replace("'", '"')), axis=1
)

或者,如果您正在阅读文件,则可以使用converters中的read_csv()选项进行阅读转化:

filename = 'path/to/file'
df = pd.read_csv(
    filename,
    converters={'Query Result': lambda x: json.loads(x.replace("'", '"'))}
)

答案 1 :(得分:0)

我相信这就是你要找的东西:

我的示例DataFrame(为简洁起见,我省略了您示例中的一些内容):

import pandas as pd
df = pd.DataFrame(columns = ['Address', 'City', 'State', 'Zip Code', 'Query Result'])
df.loc[0] = ['55 W Waterloo Rd', 'Akron', 'OH', 44319, {'field1': 'street_number', 'longname1': '55'}]
df

    Address     City    State   Zip Code    Query Result
0   55 W Waterloo Rd    Akron   OH  44319   {'longname1': '55', 'field1': 'street_number'}

诀窍似乎是访问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