【问题标题】:How do I convert a list in a Pandas DF into a string?将 Pandas DF 列表转换为字符串
【发布时间】:2016-09-17 18:43:25
【问题描述】:

我有一个熊猫数据框。其中一列包含一个列表。我希望该列是单个字符串。

例如我的列表 ['one','two','three'] 应该简单地是 'one,two,three'

df['col'] = df['col'].astype(str).apply(lambda x: ', '.join(df['col'].astype(str)))

给我 ['one, two, three],['four','five','six'] 其中第二个列表来自下一行。不用说有数百万行,这种跨行的连接不仅不正确,而且会扼杀我的记忆。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    在转换列表之前,您当然不应该转换为字符串。试试:

    df['col'].apply(', '.join)
    

    还要注意apply 将函数应用于系列的元素,因此在 lambda 函数中使用 df['col'] 可能不是您想要的。


    编辑:感谢Yakym 指出不需要 lambda 函数。

    编辑:正如Anton Protopopov 所指出的,有一个原生的.str.join 方法,但它(令人惊讶地)比apply 慢一点。

    【讨论】:

    • 谢谢。 Yakym 的代码更优雅 :) 不需要 lambda 函数。
    • 如果列表中的项目是int 类型怎么办
    • @KhalilAlHooti 这应该可以工作:df['col'].apply(lambda x: ', '.join(map(str, x)))
    • @KhalilAlHooti 这应该可以工作:df['new_col'] = df['col'].dropna().apply(lambda x: ', '.join(map(str, x)))
    • 这会过滤掉空值,但会在您创建新列时重新分配它们(因为 pandas 进行基于索引的分配,缺失值被分配为 nan)。
    【解决方案2】:

    Pandas 为此提供了一种方法,Series.str.join

    【讨论】:

      【解决方案3】:

      您可以使用astype(str) 将列表转换为str,然后删除'[] 字符。使用@Yakim 示例:

      In [114]: df
      Out[114]:
                 A
      0  [a, b, c]
      1  [A, B, C]
      
      In [115]: df.A.astype(str).str.replace('\[|\]|\'', '')
      Out[115]:
      0    a, b, c
      1    A, B, C
      Name: A, dtype: object
      

      时机

      import pandas as pd
      df = pd.DataFrame({'A': [['a', 'b', 'c'], ['A', 'B', 'C']]})
      df = pd.concat([df]*1000)
      
      
      In [2]: timeit df['A'].apply(', '.join)
      292 µs ± 10.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
      
      In [3]: timeit df['A'].str.join(', ')
      368 µs ± 24.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
      
      In [4]: timeit df['A'].apply(lambda x: ', '.join(x))
      505 µs ± 5.74 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
      
      In [5]: timeit df['A'].str.replace('\[|\]|\'', '')
      2.43 ms ± 62.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
      

      【讨论】:

      • 有趣的方法。但是,我对你的方法进行了计时,它比 apply 慢了 5 倍。
      • @IanS 你是怎么计时的?我认为这个答案中所示的矢量化字符串操作会比应用快得多
      • @Shoof 我在 IPython 中使用了 %timeit 魔法。我再次检查,发现在 100 行的列上慢了 3 倍。两种可能的解释: 1) 正则表达式替换操作,即使是矢量化的,也可能非常慢。 2)应用很聪明,例如如果您应用诸如sum 之类的标准函数,它将非常快。我认为join 可能会发生类似的事情。
      • @Shoof @IanS 我编辑了答案以添加时间。并使用str.join 添加新方法,该方法位于.apply(', '.join) 之后的第二位
      • @IanS 非常感谢定时结果!正如一些书籍所暗示的那样,这确实有点令人惊讶。很高兴看到比较!
      【解决方案4】:

      当您使用astypecol 转换为str 时,您会得到一个python 列表、括号和所有内容的字符串表示形式。你不需要这样做,直接applyjoin

      import pandas as pd
      
      df = pd.DataFrame({
          'A': [['a', 'b', 'c'], ['A', 'B', 'C']]
          })
      
      # Out[8]: 
      #            A
      # 0  [a, b, c]
      # 1  [A, B, C]
      
      df['Joined'] = df.A.apply(', '.join)
      
      #            A   Joined
      # 0  [a, b, c]  a, b, c
      # 1  [A, B, C]  A, B, C
      

      【讨论】:

      • 当我尝试这个时,它是在字母级别而不是单词级别执行的。
      • 你对 lambda 函数没有这个问题吗?
      • 这意味着你的列是一个字符串而不是一个列表。您可以使用ast.literal_eval 将其转换回来。
      • 虽然在这种情况下,只做df['col'].str.replace('[\[,\]]', '')会更快
      猜你喜欢
      • 2019-09-10
      • 1970-01-01
      • 2019-12-31
      • 2020-11-20
      • 2018-01-27
      • 2014-09-30
      • 1970-01-01
      • 2019-01-14
      • 2018-07-13
      相关资源
      最近更新 更多