【问题标题】:How to efficiently combine two columns into one column/ combine strings?如何有效地将两列组合成一列/组合字符串?
【发布时间】:2017-11-23 19:39:35
【问题描述】:

我有两列(A 和日期),如下所示,需要将它们合并为一列,如 C 列。此数据集有超过 900,000 行。

然后我遇到了两个主要问题。

  1. "Date"的数据类型是timestamp,当我将它们与字符串类型结合时会导致错误:

TypeError:+ 的不支持的操作数类型:'Timestamp' 和 'str'。

  1. 代码太费时间了。 我写了一个for循环来做如下组合:

    对于范围内的 i (0,911462): df['合并'][i]=df['日期'][i]+df['A'][i]

我猜这是因为使用 for 循环是逐行进行组合,因此每个组合都会在系统 IO 上花费大量时间。

有什么方法可以更有效地完成这项工作吗?

【问题讨论】:

  • 对不起,我对照片添加过程不熟悉,请点击超链接“在此处输入图片描述”查看数据描述。

标签: python string python-3.x pandas dataframe


【解决方案1】:

尝试使用astype,它可以将Timestamp之类的对象转换为string

import pandas as pd
df = pd.DataFrame({'A':['XX','YY','ZZ','AA'], 'Date':[pd.Timestamp("2016-01-01"),pd.Timestamp('2016-01-15'),pd.Timestamp('2016-12-01'),pd.Timestamp('2016-07-12')]})
df['Combine'] = df['Date'].astype(str) + '_'+df['A']
df

df 将是:

    A   Date        Combine
0   XX  2016-01-01  2016-01-01_XX
1   YY  2016-01-15  2016-01-15_YY
2   ZZ  2016-12-01  2016-12-01_ZZ
3   AA  2016-07-12  2016-07-12_AA

【讨论】:

  • @piRSquared 很好,我认为 OP 只是想结合A 列(str)和Date 列(时间戳)。
【解决方案2】:

您必须明确地将时间戳记为字符串,例如strftime:

In [11]: df = pd.DataFrame([[pd.Timestamp("2017-01-01"), 'a'], [pd.Timestamp("2017-01-02"), 'b']], columns=["A", "B"])

In [12]: df["A"].dt.strftime("%Y-%m-%d") + df["B"]
Out[12]:
0    2017-01-01a
1    2017-01-02b
dtype: object

【讨论】:

    【解决方案3】:

    1.左右,可以print the timestamp as a string

    关于 2. 如果你打算定期运行这个,你应该考虑使用 map/reduce。 MrJob 是一个用 python 编写的工具,它允许您在本地运行 map/reduce 作业,将它们拆分为并行运行的多个作业。检查示例,您的脚本应该非常简单。重要提示:这仅在您不担心行顺序时才有效,并且仅在您有多个可用内核时才有用。

    最好的。

    【讨论】:

      【解决方案4】:

      设置

      df = pd.DataFrame(dict(
              A='XX YY ZZ AA'.split(),
              Date=pd.date_range('2017-03-31', periods=4)
          ))
      

      选项 1
      apply 与基于 formatlambda 和字典解包。
      这是一种缓慢但很酷的方法。

      df.assign(C=df.apply(lambda x: '{Date:%Y-%m-%d}_{A}'.format(**x), 1))
      
          A       Date              C
      0  XX 2017-03-31  2017-03-31_XX
      1  YY 2017-04-01  2017-04-01_YY
      2  ZZ 2017-04-02  2017-04-02_ZZ
      3  AA 2017-04-03  2017-04-03_AA
      

      选项 2
      numpy.core.defchararray.add
      使用'datetime64[D]' 来四舍五入的非常快的方法。

      chr_add = np.core.defchararray.add
      
      d = df.Date.values.astype('datetime64[D]').astype(str)
      a = df.A.values.astype(str)
      df.assign(C=chr_add(chr_add(d, '_'), a))
      
          A       Date              C
      0  XX 2017-03-31  2017-03-31_XX
      1  YY 2017-04-01  2017-04-01_YY
      2  ZZ 2017-04-02  2017-04-02_ZZ
      3  AA 2017-04-03  2017-04-03_AA
      

      选项 3
      扯掉@AndyHayden 的答案,稍作改动。我将在strftime 中添加下划线'_'... 主要是我将在timeit 中使用的内容。

      df.assign(C=df.Date.dt.strftime('%Y-%m-%d_') + df.A)
      
          A       Date              C
      0  XX 2017-03-31  2017-03-31_XX
      1  YY 2017-04-01  2017-04-01_YY
      2  ZZ 2017-04-02  2017-04-02_ZZ
      3  AA 2017-04-03  2017-04-03_AA
      

      时机

      %%timeit
      chr_add = np.core.defchararray.add
      
      d = df.Date.values.astype('datetime64[D]').astype(str)
      a = df.A.values.astype(str)
      chr_add(chr_add(d, '_'), a)
      
      %timeit df.assign(C=df.apply(lambda x: '{Date:%Y-%m-%d}_{A}'.format(**x), 1))
      %timeit df.assign(C=df.Date.dt.strftime('%Y-%m-%d_') + df.A)
      

      小数据

      10000 loops, best of 3: 53.2 µs per loop
      1000 loops, best of 3: 1.14 ms per loop
      1000 loops, best of 3: 831 µs per loop
      

      大数据

      df = pd.concat([df] * 10000, ignore_index=True)
      
      10 loops, best of 3: 80.3 ms per loop
      1 loop, best of 3: 4.58 s per loop
      1 loop, best of 3: 233 ms per loop
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-11
        • 1970-01-01
        • 1970-01-01
        • 2015-07-22
        • 1970-01-01
        相关资源
        最近更新 更多