我有一个庞大的数据集,正在寻找可以将我的街道地址分为两列Street Number
和Street Name
的内容。
由于我首先需要处理街道地址,然后检查拆分的第一个索引是否有数字,因此我试图找出如何有效地做到这一点。
到目前为止,我的工作代码如下所示。我创建了两个函数,一个用于从街道地址中提取街道编号数据,而另一个函数则是从街道地址中替换该街道编号的第一个匹配项。
def extract_street_number(row):
if any(map(str.isdigit, row.split(" ")[0])):
return row.split(" ")[0]
def extract_street_name(address, streetnumber):
if streetnumber:
return address.replace(streetnumber, "", 1)
else:
return address
然后使用apply函数具有两列。
df[street_number] = df.apply(lambda row: extract_street_number(row[address_col]), axis=1)
df[street_name] = df.apply(lambda row: extract_street_name(row[address_col], row[street_number]), axis=1)
我想知道是否有更有效的方法来做到这一点?基于此当前例程,在处理街道名称列之前,我需要先构建“街道编号列”。
我正在考虑在地址列的第一次迭代中构建两个系列。伪代码就是这样,我无法弄清楚如何用python进行编码。
伪代码:
根据遇到非数字字符的第一个空格将地址分为两列:
street_data = address.split(" ", maxsplit=1)
如果street_data [0]有数字,则以这种方式返回列:
df[street_number] = street_data[0]
df[street_name] = street_data[1]
df[street_number] = ""
df[street_name] = street_data[0] + " " + street_data[1]
# or just simply the address
df[street_name] = address
顺便说一下,这是数据的工作样本:
# In
df = pd.DataFrame({'Address':['111 Rubin Center', 'Monroe St', '513 Banks St', '5600 77 Center Dr', '1013 1/2 E Main St', '1234C Main St', '37-01 Fair Lawn Ave']})
# Out
Street_Number Street_Name
0 111 Rubin Center
1 Monroe St
2 513 Banks St
3 560 77 Center Dr
4 1013 1/2 E Main St
5 1234C Main St
6 37-01 Fair Lawn Ave
答案 0 :(得分:1)
TL;DR: 这可以通过三个步骤来实现-
步骤 1-
df['Street Number'] = [street_num[0] if any(i.isdigit() for i in street_num[0]) else 'N/A' for street_num in df.Address.apply(lambda s: s.split(" ",1))]
步骤 2-
df['Street Address'] = [street_num[1] if any(i.isdigit() for i in street_num[0]) else 'N/A' for street_num in df.Address.apply(lambda s: s.split(" ",1))]
步骤 3-
df['Street Address'].loc[df['Street Address'].str.contains("N/A") == True] = df1['Address'].loc[df1['Street Address'].str.contains("N/A") == True]
说明-
在数据框中添加了另外两个测试用例以提高代码灵活性(第 7,8 行)-
第 1 步 - 我们将这里的街道号码与地址分开。这是通过在拆分地址字符串并初始化为 Street Number
列之后从列表中切分第一个元素来完成的。
如果第一个元素不包含数字,则将 N/A
附加到 Street Number
列中。
第 2 步 - 由于切片字符串中的第一个元素包含 Street Number
,因此第二个元素必须是 Street Address
,因此附加到 {{1} } 列。
第 3 步 - 由于第 2 步,不包含数字且由此解析的“地址”的 Street Address
变为“N/A” - >
因此,经过几个小时的努力,我们可以分三步解决这个问题。
答案 1 :(得分:0)
解决方案如下。 首先让我们划分“地址”并存储在某个地方
new = df["Address"].str.split(" ", n = 1, expand = True)
df["First Part"]= new[0]
df["Last Part"]= new[1]
接下来让我们写下条件
cond1 = df['First Part'].apply(str.isdigit)
cond2 = df['Last Part'].apply(str.isdigit)
现在检查满足给定条件的条件
df.loc[cond1 & ~cond2, "Street"] = df.loc[cond1 & ~cond2, "Last Part"]
df.loc[cond1 & ~cond2, "Number"] = df.loc[cond1 & ~cond2, "First Part"]
df.loc[~cond1 & ~cond2, "Street"] = df.loc[~cond1 & ~cond2, ['First Part', 'Last Part']].apply(lambda x: x[0] + ' ' + x[1], axis = 1)
最后,让我们清理那些辅助列
df.drop(["First Part", "Last Part"], axis = 1, inplace=True)
df
Address Street Number
0 111 Rubin Center Rubin Center 111
1 Monroe St Monroe St NaN
2 513 Banks St Banks St 513
答案 2 :(得分:0)
#mock test
df = pd.DataFrame({'Address':['111 Rubin Center', 'Monroe St',
'513 Banks St', 'Banks 513 St',
'Rub Cent 111']})
除非我缺少任何东西,否则一些正则表达式应该可以解决您的请求:
#gets number only if it starts the line
df['Street_Number'] = df.Address.str.extract(r'(^\d+)')
#splits only if number is at the start of the line
df['Street_Name'] = df.Address.str.split('^\d+').str[-1]
Address street_number street_name
0 111 Rubin Center 111 Rubin Center
1 Monroe St NaN Monroe St
2 513 Banks St 513 Banks St
3 Banks 513 St NaN Banks 513 St
4 Rub Cent 111 NaN Rub Cent 111
让我知道这在哪里下跌