过滤Pandas数据帧行并替换列中的值

时间:2017-07-07 17:21:21

标签: python pandas replace

我得到了各种格式的电话号码清单:

df = pd.DataFrame(
    {'phone': ['0123/12345', '0123-23456', '0123/4455-10', '0123-4455-22'],
     'name': ['A-1', 'B-1', 'C/3', 'D/7']})

  name phone
0 A-1  0123/12345
1 B-1  0123-23456
2 C/3  0123/4455-10
3 D/7  0123-4455-22

我想要的格式是#0和#2行。

当我专注于#1时,我尝试了以下内容:

df.loc[(df.phone.str.count('-')==1) &
       (df.phone.str.count('/')==0)].apply(lambda x: x.str.replace('-', '/'))

这就是数字上的诀窍,但不幸的是还在名称列上:

  name phone
1 B/1  0123/23456 

但不得更改名称列。

所以我有两个问题:

  1. 如何过滤该行并仅更改电话栏?
  2. 我怎样才能使用#3,在那里我想要替换第一次出现的' - '到' /'?

2 个答案:

答案 0 :(得分:7)

您只能在列手机上使用正则表达式替换(str.replace方法):

df['phone'] = df.phone.str.replace("^(\d+)-(.*)$", r"\1/\2")
df
#  name        phone
#0  A-1   0123/12345
#1  B-1   0123/23456
#2  C/3 0123/4455-10
#3  D/7 0123/4455-22

正则表达式的解释:

^(\d+)-(.*)$匹配以数字开头并紧跟破折号的字符串,这是第0行和第2行的情况;使用后向引用时,它将第一个短划线替换为/,替换为第1行和第3行,因为它们与正则表达式不匹配,不会应用任何修改。

答案 1 :(得分:1)

或者如果你不是正则表达的粉丝(就像我一样),你可以这样做:

df['phone'] = df.phone.apply(lambda x: x.replace('-','/',1) if '/' not in x else x)
print(df)

  name         phone
0  A-1    0123/12345
1  B-1    0123/23456
2  C/3  0123/4455-10
3  D/7  0123/4455-22

可能不是最好或最快的方式,因为我还不知道正则表达式,所以我感觉更舒服。

希望这很有用。