2017-06-21 111 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