How to efficiently combine two columns into one column/ combine strings?
我有两列(A和日期),如下所示,需要将它们组合成一列(C列)。这个数据集有超过90万行。
然后我遇到了两个主要问题。
TypeError: unsupported operand type(s) for +: 'Timestamp' and 'str'.
代码太费时了。我编写了一个for循环来进行组合,如下所示:
对于范围(0911462)内的I:df['combine'][i]=df['date'][i]+df['a'][i]
我想这是因为使用for循环是一行一行地进行组合,所以每个组合在系统IO上花费了大量的时间。
有什么方法可以更有效地完成这项工作吗?
您必须显式地将时间戳大小写为字符串,例如,使用strftime:
1 2 3 4 5 6 7 | 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 |
尝试使用astype,可以将
1 2 3 4 | 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 |
1 2 3 4 5 | 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 |
安装程序
1 2 3 4 | df = pd.DataFrame(dict( A='XX YY ZZ AA'.split(), Date=pd.date_range('2017-03-31', periods=4) )) |
选项1基于
1 2 3 4 5 6 7 | 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
1 2 3 4 5 6 7 8 9 10 11 | 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的答案撕下来,稍作改动。我将在
1 2 3 4 5 6 7 | 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 |
计时
1 2 3 4 5 6 7 8 9 | %%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) |
小数据
1 2 3 | 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 |
大数据
1 2 3 4 5 | 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 |
大约1,您可以将时间戳打印为字符串
大约2。如果您计划定期运行这个程序,那么应该考虑使用map/reduce。mrjob是一个用python编写的工具,它允许您在本地运行映射/减少作业,将它们拆分为多个并行运行的作业。检查示例,您的脚本应该非常简单。重要提示:只有当您不担心行顺序时,这才有效,并且只有当您有多个核心可用时才有用。
最好的。