我有两列(A和日期),如下所示,需要将它们组合成一列,如C列。此数据集有超过900,000行。
然后我遇到了两个主要问题。
"Date"
的数据类型为timestamp
,当我将它们与字符串类型组合时会导致错误:TypeError:+的不支持的操作数类型:'时间戳'和' str'。
代码太费时间了。 我写了一个for循环来进行如下组合:
for i in range(0,911462): DF ['结合'] [I] = DF ['日期'] [I] + DF [' A'] [I]
我想这是因为使用for循环逐行进行组合,因此每个组合在系统IO上花费了大量时间。
有没有办法更有效地完成这项工作?
答案 0 :(得分: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
答案 1 :(得分:3)
尝试使用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
答案 2 :(得分:2)
设置
df = pd.DataFrame(dict(
A='XX YY ZZ AA'.split(),
Date=pd.date_range('2017-03-31', periods=4)
))
选项1
apply
基于lambda
的{{1}}和字典解包
这是一种缓慢但很酷的方式。
format
选项2
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
使用numpy.core.defchararray.add
来实现这一目标非常快捷。
'datetime64[D]'
选项3
以小小的转折扯掉了@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
中添加我的下划线'_'
...主要是,这是我将在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
答案 3 :(得分:0)
关于1.,您可以print the timestamp as a string
关于2.如果您打算定期运行此功能,则应考虑使用map / reduce。 MrJob是一个用python编写的工具,它允许你在本地运行map / reduce作业,将它们分成多个并行运行的作业。查看示例,您的脚本应该非常简单。重要说明:仅当您不担心行顺序时才有效,仅当您有多个核心可用时才有用。
最佳。