【问题标题】:How can I Replace an address to have only numbers and some letters using str.replace() function in Python?如何在 Python 中使用 str.replace() 函数将地址替换为只有数字和一些字母?
【发布时间】:2021-08-28 19:43:02
【问题描述】:

我正在尝试匹配参考索引 (coClean) 上的左侧和紧缩地址(来自单独的表),这是我在 #Python #JupyterNotebook 中使用以下公式创建的

import pandas as pd
df1=pd.read_csv("/content/Addmatchdf1.csv")
df2=pd.read_csv("/content/Addmatchdf2.csv")

import re
def cleanAddress(series):
return series.str.lower().str.replace(r"[a-z\s\,]","")
df1["coClean"]=cleanAddress(df1["Address"])

df1["coClean"]=cleanAddress(df1["Address"]) 
df = pd.merge(df1, df2, 
                      on =['coClean'], 
                      how ='inner') 

这会产生一个 coClean 作为参考索引。

Address_x coClean Address_y
7 Pindara Bvd LANGWARRIN VIC 3910 73910 7 Pindara Blv, Langwarrin, VIC 3910
2a Manor St BACCHUS MARSH VIC 3340 23340 2a Manor Street, BACCHUS MARSH, VIC 3340
38 Sommersby Rd POINT COOK VIC 3030 383030 38 Sommersby Road, Point Cook, VIC 3030
17 Moira Avenue, Carnegie, Vic 3163 173163 17 Moira Avenue, Carnegie, Vic 3163
17 Moira Avenue, Carnegie, Vic 3163 173163 17 Newman Avenue, Carnegie, VIC 3163
17 Moira Avenue, Carnegie, Vic 3163 173163 17 Maroona Rd, Carnegie VIC 3163

显然,我面临的问题是,相同邮政编码下的某些地址具有相同的门牌号。但是由于参考索引相同,连接变得困难。

我怎样才能修改这个函数,使参考索引只包含

a. the house numbers
b. first four letters
c. postcode

所以 '23340'(2a manor street bacchus marsh vic 3340) 的新参考变成 '2aman3340'?因此返回一个列表,如下所示:

coClean
7pind3910
2aman3340
38somm3030
17moir3163
17newm3163
17maroo3163

我试图修改函数以包含所有字母和数字

def cleanAddress(series):
return series.str.lower().str.replace(r"[^a-z\d]","")

但是包含所有字母并不能解决问题,因为不同的表包含街道作为 st。和道路作为路。因此,更好的策略是使用带有一些首字母的门牌号和邮政编码。

感谢您的友好建议。

更新: 我换了

def cleanAddress(series):
return series.str.lower().str.replace(r"[a-z\s\,]","")
df1["coClean"]=cleanAddress(df1["Address"])

与

def cleanAddress(series):
    coclen=""
    number_of_letters=0
    if series:
        for i in range(len(series)):
            if series[i].isnumeric():
                coclen+=series[i]
            elif series[i].isalpha():
                number_of_letters+=1
                coclen+=series[i]
                if number_of_letters==4:
                    break
        for i in range(i,len(series)):
            if series[i].isnumeric():
                coclen+=series[i]
    return coclen

这会在我执行时返回错误

cleanAddress(df1["Address"])

The full error is as follows:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-17-b653a19f5638> in <module>()
----> 1 df1["coClean"]=cleanAddress(df1["Address"])

1 frames
/usr/local/lib/python3.7/dist-packages/pandas/core/generic.py in __nonzero__(self)
   1328     def __nonzero__(self):
   1329         raise ValueError(
-> 1330             f"The truth value of a {type(self).__name__} is ambiguous. "
   1331             "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
   1332         )

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

【问题讨论】:

  • 欢迎来到 Stack Overflow。请阅读How to Ask;您应该尝试自己解决问题。例如,你能编写代码找出字符串中的前四个字母是什么吗? (提示:你能写出找出所有字母的代码吗?你能写出找出前四个元素的代码吗?)
  • 谢谢@KarlKnechtel。为了证明我已经尝试“编写代码来找出所有字母是什么?”我修改了帖子,包括新代码。

标签: python regex string replace street-address


【解决方案1】:
import pandas as pd
df1 = pd.DataFrame({"Address_x":["7 Pindara Bvd LANGWARRIN VIC 3910","2a Manor St BACCHUS MARSH VIC 3340","38 Sommersby Rd POINT COOK VIC 3030","17 Moira Avenue, Carnegie, Vic 3163"],"Address_y":["7 Pindara Blv, Langwarrin, VIC 3910","2a Manor Street, BACCHUS MARSH, VIC 3340","38 Sommersby Road, Point Cook, VIC 3030","17 Moira Avenue, Carnegie, Vic 3163"]})
def cleanAddress(series):
    cocleans=[]
    for address in series:
        number_of_letters=0
        coclean=""
        for i in range(len(address)):
            if address[i].isnumeric():
                coclean+=address[i]
            elif address[i].isalpha():
                number_of_letters+=1
                coclean+=address[i]
                if number_of_letters==4:
                    break
        for i in range(i,len(address)):
            if address[i].isnumeric():
                coclean+=address[i]
        cocleans.append(coclean.lower())
    return cocleans
df1["coClean"]=cleanAddress(df1["Address_x"])

【讨论】:

  • 非常感谢您的更新。这是非常非常善良的。我按照您的建议更新了函数并尝试将函数运行为 cleanAddress(df1["Address"]) 我收到以下错误:ValueError:系列的真值不明确。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()。
  • 此函数返回包含a.门牌号、b.的字符串。前四个字母和 c。邮政编码,据我所知,你想要。如果您发布更多代码或完整的错误消息作为您发布的编辑,也许我可以解释这个错误。
  • 非常感谢您的好意。我很感激。我根据朋友的建议更新了上面的帖子。作为新用户,我非常感谢您的帮助。
  • 如果您想向 Pandas 数据框添加新列,您必须为其分配一个列表,而不仅仅是 1 个值。将您从我的函数中获得的所有 coClean 地址添加到列表中,然后将此列表分配给新列。使用此页面中的方法 I.1:re-thought.com/how-to-add-new-columns-in-a-dataframe-in-pandas。我将对我的帖子进行编辑,说明如何做到这一点。
  • 谢谢我的朋友。很有用。但是,即使我只是运行 cleanAddress 函数,我仍然会收到该错误。我编辑了我的帖子,不包括数据框中的列表。 cleanAddress 应该返回一个列表。我已经编辑了预期为每个地址返回的列表。感谢您提供非常有用的建议。数据框链接非常有用。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
相关资源
最近更新 更多