2017-06-21 179 views
4

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

enter image description here如何有效地将两列组合成一列/组合字符串?

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

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

TypeError: unsupported operand type(s) for +: 'Timestamp' and 'str'.

  • 代码太方式时间成本。 我写一个for循环做如下的组合:

    为i的范围(0,911462): DF [ '组合'] [I] = DF [ '日期'] [I] + DF [ 'A'] [i]

  • 我想这是因为使用for-loop按行进行组合,因此每个组合在系统IO上花费大量时间。

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

    +0

    对不起,我对照片添加过程并不熟悉,请点击超链接“enter image description here”查看数据说明。 –

    回答

    4

    你必须明确区分时间戳为一个字符串如与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

    尝试用astype,它可以投对象像Timestampstring

    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 
    
    +0

    @piRSquared,我想OP只是简单地想把'A'列(str)和'Date'列(Timestamp)结合起来。 –

    0

    关于1,您可以print the timestamp as a string

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

    最好。

    2

    设置

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

    选项1
    applylambda基于format和字典拆包。
    这是一个缓慢但很酷的方式来做到这一点。

    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]'舍入到一天去做。 @ AndyHayden的回答

    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
    敲竹杠与一小搓。我将在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