我有一个相当混乱的数据集,由于手动输入数据而导致许多不一致和错误。
我正在熊猫中处理此数据集的地址列。
我想做的是将地址栏分为3个单独的实体:
1)地址栏
2)街道编号列
3)一列公寓或单元号
数据如下:
address
----------------------
123 smith street #5234
5000 john ct
34 wood st apt# 23
523 fire road apt #87
charles way apt. 434
0987 misty lane unit B
我已经将街道编号移到了自己的栏中。为此,我使用了一个简单的逻辑条件“ np.where”,即如果字符串以数字开头,则将其提取到新的街道列中。
我现在对如何使用公寓号码感到困惑。
我认为由于不一致,我必须执行以下操作:
df['apt/unit'] = np.where(str contains "apt", extract string starting at "apt" until end, else np.NaN)
df['apt/unit'] = np.where(str contains "unit", extract string starting at "unit" until end, else np.NaN)
我必须使用正则表达式来执行此操作吗?如果是这样,该怎么办?
这种思路是否有其他选择?
答案 0 :(得分:2)
由于apt/unit
列具有多个条件,因此您可以像下面这样使用np.select
:
# Define our conditions
conditions = [
df.address.str.contains('apt'),
df.address.str.contains('unit'),
df.address.str.contains('#')
]
# Define our choices based on our conditions
choices = [
df.address.apply(lambda x: x[x.find('apt'):]),
df.address.apply(lambda x: x[x.find('unit'):]),
df.address.apply(lambda x: x[x.find('#'):])
]
# Apply this logic by creating the new column and cleaning up address column
df['apt/unit'] = np.select(conditions, choices, default = '')
# Clean up our address column
choices2 = [
df.address.apply(lambda x: x[:x.find('apt')]),
df.address.apply(lambda x: x[:x.find('unit')]),
df.address.apply(lambda x: x[:x.find('#')])
]
df['address'] = np.select(conditions, choices2, default = df.address)
输出
print(df)
address apt/unit
0 123 smith street #5234
1 5000 john ct
2 34 wood st apt# 23
3 523 fire road apt #87
4 charles way apt. 434
5 0987 misty lane unit B
答案 1 :(得分:1)
如果您想使用正则表达式,可以通过以下方法将数字,街道和公寓与单独的named groups匹配,然后使用df.apply填充数据框的新列。街道名称类型被列为蛮力。剩下的就是公寓号码。
regex = '(?P<num>\d+)? ?(?P<street>\w+ (street|way|st|road|ct|lane)) ?(?P<apt>.+)?'
def get_num(address):
match = re.match(regex, address)
return match.group('num')
def get_street(address):
match = re.match(regex, address)
return match.group('street')
def get_apt(address):
match = re.match(address)
return match.group('apt')
df['num'] = df['address'].apply(get_num)
df['street'] = df['address'].apply(get_street)
df['apt'] = df['address'].apply(get_apt)
答案 2 :(得分:0)
如果您已经删除了所有街道号码,则剩下的唯一号码应该是公寓号码。因此,您可以使用简单的正则表达式提取此列中剩余的所有数字:
df['apt_number'] = df.address.str.extract(r'([\d]+)')
编辑: 仅使用上面的答案,数字将保留在地址栏中,要删除该数字,我们只需将它们替换为空字符串即可:
df['address'] = df.address.str.replace(r'([\d]+)', '')