2015-10-11 94 views
3

我有以下分貝,我想爲爲3天組PAS_DATE,例如2015年3月6日的形式以2015年3月9日分組日期範圍在Python

PAS_DATE RED_DATE  TOT 
2015-03-06 2015-03-07  2 
      2015-03-17 14 
      2015-12-22  1 
2015-03-07 2015-03-08  3 
      2015-03-19  6 
      2015-10-14  2 
      2015-12-07  1 
2015-03-08 2015-09-16  8 
2015-03-09 2015-03-09  7 
      2015-03-15  6 
      2015-03-18  8 
      2015-04-04 15 
      2015-04-12 19 
      2015-05-04 44 
      2015-08-17  5 
      2015-09-09 13 
      2015-12-06  3 
      2015-12-13  3 
2015-03-10 2015-03-10  7 

的輸出應該是:

PAS_DATE RED_DATE  TOT 
2015-03-09 2015-03-07  2 
      2015-03-17 14 
      2015-12-22  1 
      2015-03-08  3 
      2015-03-19  6 
      2015-10-14  2 
      2015-12-07  1 
      2015-09-16  8 
      2015-03-09  7 
      2015-03-15  6 
      2015-03-18  8 
      2015-04-04 15 
      2015-04-12 19 
      2015-05-04 44 
      2015-08-17  5 
      2015-09-09 13 
      2015-12-06  3 
      2015-12-13  3 
2015-03-12 2015-03-10  7 

有沒有一種方法來執行此代碼,而無需Pandas或Python中的迭代?

+0

沒有迭代?你的意思是沒有任何循環構造? – tlastowka

+0

是的,我有一個大型的數據集和循環結構很慢... – user3333155

+0

這樣或那樣,你將不得不迭代行來評估數據。循環是任何從事一套或一般編程的核心構造之一。 – tlastowka

回答

0

我不知道,如果這是比使用一些循環與iterrows()更有效,但這裏是一個辦法(嗯,這是哈克雖然):

df = pd.DataFrame(pd.date_range("2015-01-01","2015-01-10"), columns=['PAS_DATE']) 

df['dt_since_first'] = (df.PAS_DATE - df.PAS_DATE.min()).dt.days 
df['shift'] = pd.to_timedelta(2 - np.mod(df.dt_since_first, 3), unit='d') 
df['for_group_by'] = df.PAS_DATE + df['shift'] 
  1. 創建一個新列從列中的第一個日期開始保存 timedelta,並將其轉換爲整數(以天數爲單位) 。
  2. 現在使用mod3來查找,PAS_DATE需要移動多少天才能獲得 到您的3天(ceil)分檔並將其轉換回timedelta對象。
  3. 只需將PAS_DATE移動此timedelta即可。

這裏是輸出:

PAS_DATE dt_since_first shift for_group_by 
0 2015-01-01    0 2 days 2015-01-03 
1 2015-01-02    1 1 days 2015-01-03 
2 2015-01-03    2 0 days 2015-01-03 
3 2015-01-04    3 2 days 2015-01-06 
4 2015-01-05    4 1 days 2015-01-06 
5 2015-01-06    5 0 days 2015-01-06 
6 2015-01-07    6 2 days 2015-01-09 
7 2015-01-08    7 1 days 2015-01-09 
8 2015-01-09    8 0 days 2015-01-09 
9 2015-01-10    9 2 days 2015-01-12 

你可以反覆做同一列,我只是用不同的列爲了便於理解的每一步......

編輯評論

我想,你的專欄PAS_DATE是dtype = object,雖然你的條目是dtype = np.datetime [64]。有一些強烈的原因,爲什麼應該避免。

我曾經有過這種情況,我自己需要一個非常長的DataFrame,直到我想通了,我經歷了地獄。有各種各樣的例外,我花了無數小時在這裏試圖解決我的問題的Stackoverflow。此外,一切都非常緩慢,最重要的是,內存要求將df保存在非常大的位置。

這是怎麼回事。您的列是dtype = object,這意味着它只保存指向大量datetime對象集合的指針。如果它是dtype = np.datetime [64],它將只保存64位的日期時間信息。

嘗試尋找的信息,它應該的東西是這樣的:

print df.info() 

Output: 
<class 'pandas.core.frame.DataFrame'> 
Int64Index: 10 entries, 0 to 9 
Data columns (total 4 columns): 
PAS_DATE   10 non-null datetime64[ns] 
dt_since_first 10 non-null int64 
shift    10 non-null timedelta64[ns] 
for_group_by  10 non-null datetime64[ns] 
dtypes: datetime64[ns](2), int64(1), timedelta64[ns](1) 
memory usage: 400.0 bytes 

現在你PAS_DATE列轉換,試試這個方法:

df.PAS_DATE = df.PAS_DATE.convert_objects(convert_dates='coerce') 

你,順便說一下,應該做的儘快在你的代碼中。而且應該也可以將它用於其他日期列。在轉換之前和之後執行df.info()。告訴我們,內存使用率之間的區別是什麼。

+0

這不是你的代碼的問題。熊貓是處理這種事情的好方法,但它仍然在迭代。 迭代現在正在熊貓包中完成,以便將數據映射到索引數據幀中。 這樣做「沒有迭代」的想法是根本上有缺陷。在某些時候,數據集必須拆分成行,並且每行都必須以某種方式進行評估,無論是通過其實際內容還是通過與其他行相關的元數據進行評估。 – tlastowka

+0

@tlastowka當然你是對的。簡單地說,因爲相同的操作多次完成(字面上每個**行**),肯定會有循環。實際上其中的一些,因爲我的代碼需要在數據幀上多次迭代。儘管如此,這是現在矢量化和numpy正在以高度優化的方式進行操作。我想這是更快,但也需要更多的內存。 – user2532323