将无序的元组列表转换为pandas DataFrame

时间:2017-12-15 16:01:06

标签: python python-3.x pandas tuples concat

我使用库usaddress来解析我拥有的一组文件中的地址。我希望我的最终输出是一个数据框,其中列名称代表地址的一部分(例如街道,城市,州),行代表我提取的每个单独的地址。例如:

假设我有一个地址列表:

addr = ['123 Pennsylvania Ave NW Washington DC 20008', 
        '652 Polk St San Francisco, CA 94102', 
        '3711 Travis St #800 Houston, TX 77002']

我使用usaddress

提取它们
info = [usaddress.parse(loc) for loc in addr]

"信息"是一个如下所示的元组列表列表:

[[('123', 'AddressNumber'),
  ('Pennsylvania', 'StreetName'),
  ('Ave', 'StreetNamePostType'),
  ('NW', 'StreetNamePostDirectional'),
  ('Washington', 'PlaceName'),
  ('DC', 'StateName'),
  ('20008', 'ZipCode')],
 [('652', 'AddressNumber'),
  ('Polk', 'StreetName'),
  ('St', 'StreetNamePostType'),
  ('San', 'PlaceName'),
  ('Francisco,', 'PlaceName'),
  ('CA', 'StateName'),
  ('94102', 'ZipCode')],
 [('3711', 'AddressNumber'),
  ('Travis', 'StreetName'),
  ('St', 'StreetNamePostType'),
  ('#', 'OccupancyIdentifier'),
  ('800', 'OccupancyIdentifier'),
  ('Houston,', 'PlaceName'),

我希望每个列表(对象中有3个列表" info")表示一行,每个元组对的2值表示一列和1的值元组对是值。注意:内部列表的链接并不总是相同,因为并非每个地址都包含所有信息。

非常感谢任何帮助!

由于

2 个答案:

答案 0 :(得分:2)

不确定是否有一个DataFrame构造函数可以完全像现在一样处理info。 (也许from_recordsfrom_items? - 仍然认为此结构不会直接兼容。)

这是一些操作来获得你想要的东西:

cols = [j for _, j in info[0]]

# Could use nested list comprehension here, but this is probably
#     more readable.
info2 = []
for row in info:
    info2.append([i for i, _ in row])

pd.DataFrame(info2, columns=cols)

  AddressNumber    StreetName StreetNamePostType StreetNamePostDirectional   PlaceName StateName ZipCode
0           123  Pennsylvania                Ave                   NW       Washington        DC   20008
1           652          Polk                 St                  San       Francisco,        CA   94102

答案 1 :(得分:1)

感谢您的回复!我最终做了一个完全不同的解决方法如下:

我查看了文档以查看usaddress中所有可能的parse_tags,创建了一个包含所有可能标记作为列的DataFrame,以及另一个包含解压缩地址的列。然后我继续使用regex解析并从列中提取信息。代码如下!

parse_tags = ['Recipient','AddressNumber','AddressNumberPrefix','AddressNumberSuffix',
'StreetName','StreetNamePreDirectional','StreetNamePreModifier','StreetNamePreType',
'StreetNamePostDirectional','StreetNamePostModifier','StreetNamePostType','CornerOf',
'IntersectionSeparator','LandmarkName','USPSBoxGroupID','USPSBoxGroupType','USPSBoxID',
'USPSBoxType','BuildingName','OccupancyType','OccupancyIdentifier','SubaddressIdentifier',
'SubaddressType','PlaceName','StateName','ZipCode']

addr = ['123 Pennsylvania Ave NW Washington DC 20008', 
        '652 Polk St San Francisco, CA 94102', 
        '3711 Travis St #800 Houston, TX 77002']

df = pd.DataFrame({'Addresses': addr})
pd.concat([df, pd.DataFrame(columns = parse_tags)])

然后我创建了一个新列,该列从usaddress解析列表中创建了一个字符串并将其命名为" Info"

df['Info'] = df['Addresses'].apply(lambda x: str(usaddress.parse(x)))

现在,这是主要的解决方法。我循环遍历每个列名称并在相应的" Info"中找到它。单元格和应用正则表达式来提取它们存在的信息!

for colname in parse_tags:
    df[colname] = df['Info'].apply(lambda x: re.findall("\('(\S+)', '{}'\)".format(colname), x)[0] if re.search(
    colname, x) else "")

这可能不是最有效的方式,但它适用于我的目的。谢谢大家提供建议!

相关问题