【问题标题】:How to replace specific digits in column using python pandas.如何使用 python pandas 替换列中的特定数字。
【发布时间】:2018-12-20 02:45:06
【问题描述】:

如何在不影响其他字符的情况下替换熊猫数据框列中的特定数字?我有一个类似这样的大型 csv 文件:

data = pd.read_csv("meter.csv")
data.head()
Out[10]:
     value  temp1  temp2
0   34 02:0   16.0     17 
1   36 06:0    8.0     27
2   28 10:0   18.0     21
3   34 02:0   16.0     17 
4   36 06:0    8.0     27
5   28 10:0   18.0     21
6   34 02:0   16.0     17 
7   36 06:0    8.0     27
8   28 10:0   18.0     21

如果value.str[3:5] == 10 使用00,我想替换value 列值

我需要的输出:

     value  temp1  temp2
0   34 02:0   16.0     17 
1   36 06:0    8.0     27
2   28 00:0   18.0     21
3   34 02:0   16.0     17 
4   36 06:0    8.0     27
5   28 00:0   18.0     21
6   34 02:0   16.0     17 
7   36 06:0    8.0     27
8   28 00:0   18.0     21

我尝试使用pd.str.replace 参考:pandas.Series.str.replace。但无法实现。

我的代码:data['value'] = data['value'].str[3:5].replace('10','00') 这给出了输出:

   value  temp1  temp2
0   02   16.0     17 
1   06    8.0     27
2   00   18.0     21
3   02   16.0     17 
4   06    8.0     27
5   00   18.0     21

它正在用新值替换整个值。谁能帮我解决这个问题。 谢谢!

【问题讨论】:

    标签: python pandas dataframe conditional-statements str-replace


    【解决方案1】:

    你可以使用 np.where

    df.value=np.where(df.value.str[3:5]=='10',df.value.str[:3]+'10'+df.value.str[5:],df.value)
    df
    Out[21]: 
         value  temp1  temp2
    0  34 02:0   16.0     17
    1  36 06:0    8.0     27
    2  28 10:0   18.0     21
    3  34 02:0   16.0     17
    4  36 06:0    8.0     27
    5  28 10:0   18.0     21
    6  34 02:0   16.0     17
    7  36 06:0    8.0     27
    8  28 10:0   18.0      2
    

    或受到托马斯的启发

    df.value.str.replace(r'\s10\:',' 00:')
    

    【讨论】:

    • 非常感谢您提供替代解决方案!
    【解决方案2】:

    使用str.slice

    mask=df.value.str.slice(3,5) =='10'
    
    df.loc[mask, 'value'] = df.loc[mask].value.str.slice(0,3) + '00' +  df.loc[mask].value.str.slice(5,) 
    

    【讨论】:

      【解决方案3】:

      data['value'].str[3:5].replace('10','00') 返回一个pd.Series,由[3:5] 切片的每个字符串组成,每行应用replace 方法。您正在寻找的是返回整个字符串,并在与您的条件匹配的每一行中应用replace,可以这样实现:

      import pandas as pd
      
      data = pd.DataFrame({ # small part of your DF
          'value': ['34 02:0', '36 06:0', '28 10:0'], # Third row should be changed
          'temp1': [16.0, 8.0, 18.0],
          'temp2': [17, 27, 21] 
      })
      
      mask = data['value'].str[3:5] == '10'
      data.loc[mask, 'value'] = data.loc[mask, 'value'].str.replace('10', '00')
      
      >>> print(data)
           value  temp1  temp2
      0  34 02:0   16.0     17
      1  36 06:0    8.0     27
      2  28 00:0   18.0     21 # Third row changes, yay!
      

      如果有一个值多次匹配“10”,例如10 10:0,则此代码可能会引入错误。你可以通过调用.replace('10:', '00:') 来解决这个问题。

      您也可以只使用正则表达式来匹配 r'\s10\:' 之类的内容并调用 .replace(re.compile(r'\s10\:'), ' 00:')

      import re
      
      r = re.compile(r'\s10\:')
      data['value'] = data['value'].str.replace(r, ' 00:', regex=True) # no need to define a condition at all
      
      >>> print(data)
           value  temp1  temp2
      0  34 02:0   16.0     17
      1  36 06:0    8.0     27
      2  28 00:0   18.0     21
      

      根据您的情况,最后一个解决方案不如第一个解决方案那么明确。

      【讨论】:

      • 精彩而清晰的解释!非常感谢!
      • 精彩而清晰的解释!非常感谢!
      【解决方案4】:

      如果有多个条件和选择,我更喜欢

      condition = [df.value.str[3:5]=='10']
      choice= [df.value.str[:3]+'10'+df.value.str[5:]]
      df.value= np.select(condition,choice,default=df.value)
      
      #inspired by Beny
      

      输出

        value  temp1  temp2
      0  34 02:0   16.0     17
      1  36 06:0    8.0     27
      2  28 10:0   18.0     21
      3  34 02:0   16.0     17
      4  36 06:0    8.0     27
      5  28 10:0   18.0     21
      6  34 02:0   16.0     17
      7  36 06:0    8.0     27
      8  28 10:0   18.0      2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-13
        • 2018-12-22
        • 2021-09-17
        • 2021-05-18
        • 1970-01-01
        相关资源
        最近更新 更多