【问题标题】:pandas.DataFrame.replace, and for the first columnpandas.DataFrame.replace 和第一列
【发布时间】:2016-07-28 19:06:05
【问题描述】:

如何使用pandas.DataFrame.replace 替换熊猫数据框中所有出现的字符串?

这似乎是一个相当愚蠢的问题,但请take a look here,

即,在以下三个DataFrame.replace 中,只有一个在工作,另外两个不在。我该如何修复它们?

另外,如何限制第一列内的替换? (我尝试使用, axis=1,但被告知它现在已被弃用)。谢谢。

df = pd.DataFrame({'A': np.random.choice(['foo', 'bar'], 100),
                   'B': np.random.choice(['one', 'two', 'three'], 100),
                   'C': np.random.choice(['I1', 'I2', 'I3', 'I4'], 100),
                   'D': np.random.randint(-10,11,100),
                   'E': np.random.randn(100)})

p = pd.pivot_table(df, index=['A','B'], columns='C', values='D')
df.replace("fo","fu", regex=True,inplace=True)
p.replace("fo","fu", regex=True,inplace=True)
p.index = p.index.to_series().str.join('-')
r=p.copy()
r.replace("fo","fu", regex=True,inplace=True)

【问题讨论】:

    标签: python python-3.x replace dataframe


    【解决方案1】:

    只在一列中进行替换

    将该列作为一个系列获取并使用Series.replace 方法:

    df['A'] = df['A'].replace("fo", "fu", regex=True)
    

    或

    df['A'].replace("fo", "fu", regex=True, inplace=True)
    

    在索引中进行替换

    Series.replace 和 DataFrame.replace 都只作用于数据本身,而不作用于索引。您需要将索引重置为列,进行替换并重新设置索引。

    r = p.copy()
    r.index = r.index.to_series().str.join('-')
    r.index.name = 'A-B'
    
    r = (r.reset_index()                     # reset the index
          .replace('fo', 'fu', regex=True)   # make the replacement
          .set_index('A-B'))                 # set the index again
    

    你可以把它和上面的结合起来——所以替换只有发生在索引中。

    r = p.copy()
    r.index = r.index.to_series().str.join('-')
    r.index.name = 'A-B'
    
    r = r.reset_index()
    r['A-B'] = r['A-B'].replace('fo', 'fu', regex=True)
    r = r.set_index('A-B')
    

    @juanpa.arrivillaga 的代码更短:

    r.index = r.index.to_series().replace('fo','fu', regex=True)
    

    在MultiIndex 中进行替换

    同样,您需要重置您想要的MultiIndex 的任何级别,进行替换并将其放回索引中。

    p = (p.reset_index(level='A')            # reset only level 'A'
          .replace('fo', 'fu', regex=True)   # make the replacement
          .set_index('A', append=True)       # send 'A' to the index again
          .swaplevel())                      # if you want 'A' before 'B'
    

    或者,仅在该索引级别进行替换:

    p = p.reset_index(level='A')
    p['A'] = p['A'].replace('fo', 'fu', regex=True)
    p = p.set_index('A', append=True).swaplevel()
    

    但请注意

    p.index = p.index.to_series().replace('fo', 'fu', regex=True)
    

    这里没有给出你想要的——它用一个普通的索引替换了MultiIndex。

    【讨论】:

    • 非常感谢您的全面回答。我会检查他们并回复你。关于第一列中的替换,如何通过索引而不是字段名来引用它?我正在编写一个不知道第一列字段名称到底是哪个的库。谢谢。
    • 如果不知道列名是A,请使用df.iloc[:,0]而不是df['A']
    【解决方案2】:

    replace 的另外两种用法的问题是,replace 仅适用于列中的值,而不适用于索引中的值,并且在 p 和 r 中,'fo' 仅在索引中找到!因此,一种可行的方法是:

    p.index = p.index.to_series().replace('fo','fu', regex=True)
    r.index = r.index.to_series().replace('fo','fu', regex=True)
    

    所以,你看...

    >>> r.index = r.index.to_series().replace('fo','fu', regex=True)
    >>> r
    C                I1        I2        I3        I4
    bar-one    6.666667  1.875000 -3.750000  6.000000
    bar-three -1.750000 -4.000000 -2.200000 -1.000000
    bar-two    4.000000 -2.666667 -4.333333  4.000000
    fuo-one    5.400000 -0.400000  4.000000  0.000000
    fuo-three  0.166667 -4.500000 -5.000000 -5.571429
    fuo-two    2.100000 -4.000000  4.500000 -1.857143
    

    一般来说,如果你只想替换单个列,你需要使用类似的东西:

    df.loc[:,'B'].replace('th','TH', regex=True, inplace=True)
    

    所以...

    >>> df.loc[:,'B'].replace('th','TH', regex=True, inplace=True)
    >>> df.head(10)
         A      B   C  D         E
    0  bar    two  I3 -7  1.212562
    1  bar    two  I3 -9  1.480350
    2  bar    one  I2  1 -1.555152
    3  fuo    two  I2 -9 -1.754800
    4  bar    one  I3 -4  1.455140
    5  fuo  THree  I4 -9  0.131374
    6  fuo    one  I4 -7  1.876776
    7  fuo    one  I1  3  0.170372
    8  bar    two  I1  3 -0.647829
    9  bar    one  I3 -1  0.796723
    

    注意,后一种构造也可以让您控制行!

    >>> df.loc[0:5,'B'].replace('on','ON', regex=True, inplace=True)
    >>> df.head(10)
         A      B   C  D         E
    0  bar    two  I3 -7  1.212562
    1  bar    two  I3 -9  1.480350
    2  bar    ONe  I2  1 -1.555152
    3  fuo    two  I2 -9 -1.754800
    4  bar    ONe  I3 -4  1.455140
    5  fuo  THree  I4 -9  0.131374
    6  fuo    one  I4 -7  1.876776
    7  fuo    one  I1  3  0.170372
    8  bar    two  I1  3 -0.647829
    9  bar    one  I3 -1  0.796723
    

    【讨论】:

    • 嗨,p.index = p.index.to_series().replace('fo', 'fu', regex=True) 将用普通索引替换 MultiIndex,不是吗?对我来说这并不重要,但想确认一下。谢谢。
    • @xpt 实际上它给了我一个段错误!你能帮我试试吗?我想我只是在之后之前在我的机器上尝试过它,我已经完成了p.index = p.index.to_series().str.join('-')
    • 它没有对我造成段错误,但它也没有工作。我在C 列中得到了(foo, one)。
    猜你喜欢
    • 2020-04-17
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    • 2023-03-13
    • 2017-12-17
    • 1970-01-01
    相关资源
    最近更新 更多