在一個虛擬的數據和40K行中A
和100行中B
設置,下面 辦法是約1000倍比使用.apply
與所提供的功能,更快。
假設乙看起來如下幀,
>>> B
StartDate EndDate Amount
0 2000-01-01 2000-01-16 10
1 2000-02-01 2000-02-16 20
2 2000-03-01 2000-03-16 30
3 2000-04-01 2000-04-16 40
4 2000-05-01 2000-05-16 50
... ... ...
[100 rows x 3 columns]
B可被翻譯,如下所示,與一個索引的TimeSeries該 含有B的範圍和相應的「金額定義每天' 值。
def make_series(start, end, amount):
idx = pd.date_range(start, end, freq='D', closed='left')
return pd.Series([amount] * len(idx), index=idx)
def make_series2(s):
idx = pd.date_range(s['StartDate'], s['EndDate'], freq='D', closed='left')
return pd.Series([s['Amount']] * len(idx), index=idx)
# for non-overlapping ranges
>>> B2 = pd.concat([make_series(s, e, a) for _, s, e, a in B.itertuples()])
# for overlapping ranges
>>> B2 = B.apply(make_series2, axis=1).bfill().T[0]
>>> timeit B2 = pd.concat([make_series(s, e, a) for _, s, e, a in B.itertuples()])
100 loops, best of 3: 15.9 ms per loop
>>> timeit B2 = B.apply(make_series2, axis=1).bfill().T[0]
10 loops, best of 3: 54.9 ms per loop
>>> B2
2000-01-01 10
2000-01-02 10
...
2008-04-14 1000
2008-04-15 1000
Length: 1500
的最後一步是索引到B2
使用A.Date
:
>>> A['Amount'] = B2[A.Date].fillna(0).values
>>> timeit A['Amount'] = B2[A.Date].fillna(0).values
1000 loops, best of 3: 1.91 ms per loop
爲了便於比較,這裏的apply
在同一幀使用timeit:
>>> timeit A.apply(find, axis=1)
1 loops, best of 3: 26.3 s per loop
你能告訴一個小樣本表「A」和「B」? –