将元组的无序列表转换为 pandas DataFrame
Converting unordered list of tuples to pandas DataFrame
我正在使用库 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]
"info" 是元组列表的列表,如下所示:
[[('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'),
我希望每个列表(对象 "info" 中有 3 个列表)表示一行,每个元组对的 2 值表示一列和 1 值元组对的值。 注意:内部列表的 link 并不总是相同的,因为并非每个地址都有所有信息。
如有任何帮助,我们将不胜感激!
谢谢
不确定是否有一个 DataFrame 构造函数可以完全按照您现在的方式处理 info
。 (也许 from_records
或 from_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
感谢您的回复!我最终做了一个完全不同的解决方法,如下所示:
我检查了文档以查看 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 "")
这可能不是最有效的方法,但它对我的目的有用。感谢大家提供建议!
我正在使用库 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]
"info" 是元组列表的列表,如下所示:
[[('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'),
我希望每个列表(对象 "info" 中有 3 个列表)表示一行,每个元组对的 2 值表示一列和 1 值元组对的值。 注意:内部列表的 link 并不总是相同的,因为并非每个地址都有所有信息。
如有任何帮助,我们将不胜感激!
谢谢
不确定是否有一个 DataFrame 构造函数可以完全按照您现在的方式处理 info
。 (也许 from_records
或 from_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
感谢您的回复!我最终做了一个完全不同的解决方法,如下所示:
我检查了文档以查看 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 "")
这可能不是最有效的方法,但它对我的目的有用。感谢大家提供建议!