【问题标题】:add a string prefix to each value in a string column using Pandas使用 Pandas 为字符串列中的每个值添加字符串前缀
【发布时间】:2013-11-30 07:26:46
【问题描述】:

我想在 Pandas 数据框的所述列中的每个值的开头附加一个字符串(优雅地)。 我已经想出了如何做到这一点,我目前正在使用:

df.ix[(df['col'] != False), 'col'] = 'str'+df[(df['col'] != False), 'col']

这似乎是一件非常不雅的事情——你知道其他方法吗(也可能将字符添加到该列为 0 或 NaN 的行)?

如果这还不清楚,我想转:

    col 
1     a
2     0

进入:

       col 
1     stra
2     str0

【问题讨论】:

  • 你到底在问什么?请解释你的代码做什么/希望它做什么
  • 我认为示例代码的作用对于普通的 pandas 用户来说非常清楚。为了您的方便,我添加了用例示例。
  • 您的描述与您的代码有些不一致。 != False 业务怎么了?您想将str 添加到每个值还是只添加一些?
  • 到每个值,如我的示例数据框所示。
  • 你的例子还有点不清楚,你想要df['col'] = 'str' + df['col'].astype(str)这样的东西吗?

标签: python string pandas dataframe


【解决方案1】:

你可以使用pandas.Series.map

df['col'].map('str{}'.format)

在此示例中,它将在您的所有值之前应用单词 str

【讨论】:

    【解决方案2】:

    在为诸如 csv 导出上的人类可读值之类的东西控制 NaN 的同时为列添加前缀。

    "_" + df['col1'].replace(np.nan,'').astype(str)

    例子:

    import sys
    import platform
    import pandas as pd
    import numpy as np
    
    print("python {}".format(platform.python_version(), sys.executable))
    print("pandas {}".format(pd.__version__))
    print("numpy {}".format(np.__version__))
    
    df = pd.DataFrame({
        'col1':["1a","1b","1c",np.nan],
        'col2':["2a","2b",np.nan,"2d"], 
        'col3':[31,32,33,34],
        'col4':[np.nan,42,43,np.nan]})
    
    df['col1_prefixed'] = "_" + df['col1'].replace(np.nan,'no value').astype(str)
    df['col4_prefixed'] = "_" + df['col4'].replace(np.nan,'no value').astype(str)
    
    print(df)
    
    python 3.7.3
    pandas 1.2.3
    numpy 1.18.5
      col1 col2  col3  col4 col1_prefixed col4_prefixed
    0   1a   2a    31   NaN           _1a     _no value
    1   1b   2b    32  42.0           _1b         _42.0
    2   1c  NaN    33  43.0           _1c         _43.0
    3  NaN   2d    34   NaN     _no value     _no value
    

    (抱歉冗长,我在处理不相关的列类型问题时发现了这个 Q,这是我的复制代码)

    【讨论】:

    • 我觉得pd.Series([None]).astype('str')[0] == 'None' 很麻烦。与np.nan 类似。字符串 "None" 是真实的,但 None 不是。该解决方案有助于解决 +1
    【解决方案3】:

    .loc 的另一种解决方案:

    df = pd.DataFrame({'col': ['a', 0]})
    df.loc[df.index, 'col'] = 'string' + df['col'].astype(str)
    

    这不如上述解决方案快(每循环慢 1 毫秒),但在您需要有条件的更改时可能很有用,例如:

    mask = (df['col'] == 0)
    df.loc[mask, 'col'] = 'string' + df['col'].astype(str)
    

    【讨论】:

      【解决方案4】:

      作为替代方案,您还可以使用 applyformat 结合使用(或使用 f-strings 更好),我发现如果使用例如还想添加后缀或操作元素本身:

      df = pd.DataFrame({'col':['a', 0]})
      
      df['col'] = df['col'].apply(lambda x: "{}{}".format('str', x))
      

      这也产生了所需的输出:

          col
      0  stra
      1  str0
      

      如果你使用 Python 3.6+,你也可以使用 f-strings:

      df['col'] = df['col'].apply(lambda x: f"str{x}")
      

      产生相同的输出。

      f-string 版本几乎和@RomanPekar 的解决方案一样快(python 3.6.4):

      df = pd.DataFrame({'col':['a', 0]*200000})
      
      %timeit df['col'].apply(lambda x: f"str{x}")
      117 ms ± 451 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
      
      %timeit 'str' + df['col'].astype(str)
      112 ms ± 1.04 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
      

      然而,使用format 确实慢得多:

      %timeit df['col'].apply(lambda x: "{}{}".format('str', x))
      185 ms ± 1.07 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
      

      【讨论】:

      • 相同的结果,但速度较慢;-)
      • @Philipp_Kats:我添加了一些时间,感谢您的建议!似乎 f 弦几乎一样快。 format 确实表现更差。你是怎么比较的?
      • 哦,太好了!据我了解,.apply 总是比“直接”矢量化操作快或慢;即使它们不慢,我更愿意尽可能避免它们。
      • @Philipp_Kats:我同意,但是,在这种特殊情况下,我发现当我还添加一个后缀、对 x 本身做一些事情等时,它更具可读性,但这只是个人喜好问题。 .. :)
      【解决方案5】:

      如果您使用 dtype=str 加载表格文件
      或将列类型转换为字符串df['a'] = df['a'].astype(str)
      那么你可以使用这样的方法:

      df['a']= 'col' + df['a'].str[:]
      

      这种方法允许df 的前置、附加和子集字符串。
      适用于 Pandas v0.23.4、v0.24.1。不知道早期版本。

      【讨论】:

        【解决方案6】:
        df['col'] = 'str' + df['col'].astype(str)
        

        例子:

        >>> df = pd.DataFrame({'col':['a',0]})
        >>> df
          col
        0   a
        1   0
        >>> df['col'] = 'str' + df['col'].astype(str)
        >>> df
            col
        0  stra
        1  str0
        

        【讨论】:

        • 谢谢。如果感兴趣,数据帧索引也支持这样的字符串操作。
        • 如果在连接之前必须满足条件,我该怎么做?
        • @tagoma,4 年后,是的:它还支持数据帧索引。您可以创建一个新列并附加到索引值:df['col'] = 'str'+df.index.astype(str)
        • "astype(str)" 如果您最终尝试保存到文件,可能会破坏编码。
        • 当我尝试这个以及任何其他方法时,我得到一个 SettingWithCopyWarning。有办法避免吗?
        猜你喜欢
        • 2021-10-20
        • 2018-07-12
        • 2011-09-12
        • 2018-05-08
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多