Tôi có các khung dữ liệu với các chỉ số DateTime các loại khác nhau (có thể là dữ liệu hàng tuần, hàng tháng, hàng năm). Tôi muốn tạo các cột có giá trị trễ của các cột khác. Tôi nhận được những nhập khẩu từ một bảng tính, tôi không tạo ra các chỉ số datetime bên trong python.Cách Pythonic để làm trễ các cột được lập chỉ mục thời gian
Tôi đang đấu tranh để tìm cách 'pythonic' để thực hiện việc này. Tôi tính nếu tôi sử dụng khả năng datetime của Pandas, sự chậm trễ có thể mạnh mẽ hơn trong trường hợp dữ liệu lạ hoặc đặc biệt.
Tôi đã tạo một ví dụ đồ chơi có vẻ hoạt động, nhưng nó không thành công trên ví dụ thực tế của tôi.
Ví dụ đồ chơi mà hoạt động chính xác (làm cho một cột mới có giá trị 'foo' của tháng trước)
rng = pd.date_range('2012-01-01', '2013-1-01', freq="M")
toy2 = pd.DataFrame(pd.Series(np.random.randint(0, 50, len(rng)), index=rng, name="foo"))
foo
2012-01-31 4
2012-02-29 2
2012-03-31 27
2012-04-30 7
2012-05-31 44
2012-06-30 22
2012-07-31 16
2012-08-31 18
2012-09-30 35
2012-10-31 35
2012-11-30 16
2012-12-31 32
toy2['lag_foo']= toy2['foo'].shift(1,'m')
foo lag_foo
2012-01-31 4 NaN
2012-02-29 2 4.0
2012-03-31 27 2.0
2012-04-30 7 27.0
2012-05-31 44 7.0
2012-06-30 22 44.0
2012-07-31 16 22.0
2012-08-31 18 16.0
2012-09-30 35 18.0
2012-10-31 35 35.0
2012-11-30 16 35.0
2012-12-31 32 16.0
Nhưng khi tôi chạy trên ví dụ thực tế cuộc sống của tôi, nó không thành công với:
ValueError: cannot reindex from a duplicate axis
print type(toy)
print toy.columns
print toy['IPE m2'][0:5]
<class 'pandas.core.frame.DataFrame'>
Index([u'IPE m2'], dtype='object')
Date
2016-04-30 43.29
2016-03-31 40.44
2016-02-29 34.17
2016-01-31 32.47
2015-12-31 39.35
Name: IPE m2, dtype: float64
ngoại lệ dấu vết:
ValueError Traceback (most recent call last)
<ipython-input-170-9cb57a2ed681> in <module>()
----> 1 toy['prev_1m']= toy['IPE m2'].shift(1,'m')
C:\Users\mds\Anaconda2\lib\site-packages\pandas\core\frame.pyc in __setitem__(self, key, value)
2355 else:
2356 # set column
-> 2357 self._set_item(key, value)
2358
2359 def _setitem_slice(self, key, value):
C:\Users\mds\Anaconda2\lib\site-packages\pandas\core\frame.pyc in _set_item(self, key, value)
2421
2422 self._ensure_valid_index(value)
-> 2423 value = self._sanitize_column(key, value)
2424 NDFrame._set_item(self, key, value)
2425
C:\Users\mds\Anaconda2\lib\site-packages\pandas\core\frame.pyc in _sanitize_column(self, key, value)
2555
2556 if isinstance(value, Series):
-> 2557 value = reindexer(value)
2558
2559 elif isinstance(value, DataFrame):
C:\Users\mds\Anaconda2\lib\site-packages\pandas\core\frame.pyc in reindexer(value)
2547 # duplicate axis
2548 if not value.index.is_unique:
-> 2549 raise e
2550
2551 # other
ValueError: cannot reindex from a duplicate axis
Có vẻ như tôi đang thiếu một số tinh tế của các chỉ số thời gian của Pandas mà tôi nghĩ. Plus Tôi thậm chí không chắc chắn đây là cách lý tưởng để làm điều này. điều duy nhất tôi có thể nghi ngờ là toy.index không làm việc có Không như các kim loại, trong khi làm việc toy2 Ví dụ, có tần số của nó đặt là 'M'
toy.index
DatetimeIndex(['2016-04-30', '2016-03-31', '2016-02-29', '2016-01-31',
'2015-12-31', '2015-11-30', '2015-10-31', '2015-09-30',
'2015-08-31', '2015-07-31',
...
'NaT', 'NaT', 'NaT', 'NaT',
'NaT', 'NaT', 'NaT', 'NaT',
'NaT', 'NaT'],
dtype='datetime64[ns]', name=u'Date', length=142, freq=None)
toy2.index
DatetimeIndex(['2012-01-31', '2012-02-29', '2012-03-31', '2012-04-30',
'2012-05-31', '2012-06-30', '2012-07-31', '2012-08-31',
'2012-09-30', '2012-10-31', '2012-11-30', '2012-12-31'],
dtype='datetime64[ns]', freq='M')
In [ ]:
======== ===================
tôi ném đi của NAT
toy = toy.dropna()
toy['prev_1m']= toy['IPE m2'].shift(1,'m')
và tôi làm có được kết quả tôi muốn. Tuy nhiên, tôi cũng có được một cảnh báo:
C:\Users\mds\Anaconda2\lib\site-packages\ipykernel\__main__.py:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
if __name__ == '__main__':
====
cách này của nhiệm vụ ngăn chặn những lời cảnh báo:
toy.loc[:,'prev_1m2']= toy['IPE m2'].shift(1,'m')
Tôi đã sử dụng dropna() để loại bỏ các NaT, và nó hoạt động, tuy nhiên nó đưa ra một số cảnh báo. Đã thêm phụ lục cho câu hỏi gốc. – user3556757
Bạn có chắc là bạn cần 'dropna'? Nó loại bỏ tất cả các hàng có 'NaN' trong cột. Nếu có, sử dụng' copy': 'toy = toy.dropna(). Copy()' Nếu cần xóa các bản ghi với 'NaN' trong chỉ mục, sử dụng' toy = toy [ pd.notnull (toy.index)] '. – jezrael