2017-03-06 9 views
1

データを半年に分割したいと考えています。私のサンプルデータの下では、結果は2つの別々のデータフレームである必要があります.1つは年の最初の50%ともう1つはもう1つのデータフレームです。追加の条件は、50%が列 'LG'に基づいている必要があるということです。日付を基準に半分のデータを分割する

誰もがこれを手伝ってくれますか?

サンプルデータ:

import pandas as pd 
import numpy as np 

df = pd.DataFrame(
    {'LG' : ('AR1', 'AR1', 'AR1', 'AR1', 'AR1', 'AR1', 'PO1', 'PO1', 'AR1', 'AR1', 'PO1', 'PO1'), 
    'Date': ('2011-1-1', '2011-3-1', '2011-4-1', '2011-2-1', '2012-1-1', '2012-2-1', '2012-1-1', '2012-2-1', '2013-1-1', '2013-2-1', '2013-1-1', '2013-2-1'), 
    'Year': (2011, 2011, 2011, 2011, 2012, 2012, 2012, 2012, 2013, 2013, 2013, 2013)}) 

pd.to_datetime(df['Date']) 

DF:

  Date LG Year 
0 2011-01-01 AR1 2011 
1 2011-03-01 AR1 2011 
2 2011-04-01 AR1 2011 
3 2011-02-01 AR1 2011 
4 2012-01-01 AR1 2012 
5 2012-02-01 AR1 2012 
6 2012-01-01 PO1 2012 
7 2012-02-01 PO1 2012 
8 2013-01-01 AR1 2013 
9 2013-02-01 AR1 2013 
10 2013-01-01 PO1 2013 
11 2013-02-01 PO1 2013 
+3

'のDF [ '日付']適用(pd.to_datetime) 'は、' pd.to_datetime(df ['Date']) 'と言うのが遅いです。 –

+0

あなたの編集したコメント – Zanshin

答えて

1

YearLGにグループ分けした後、半分にフレームを分割します。フレームがする必要がある場合

:日付でソートする

# group by 'Year' and 'LG' 
idx = ['Year', 'LG'] 

# build a grouper 
group_by = df.groupby(idx, as_index=False) 

# need frame to re-expand the group size 
df1 = df.set_index(idx) 
df1['g_size'] = group_by.size() 

# find the rows in the top half of respective group 
top_half = (group_by.cumcount()/df1.g_size.values).values < 0.5 

# build new data frames 
top = df.loc[top_half] 
bot = df.loc[~top_half] 

コード:基本的な考え方は、グループサイズ

コードの50%未満であるグループ内の場所を見つけることです分割前の日付で並べ替えることはできますが、元のデータフレームに並べ替えることは望ましくありません。

# group by 'Year' and 'LG' 
idx = ['Year', 'LG'] 

# sort by date 
df1 = df.sort('Date') 

# build a grouper 
group_by = df1.groupby(idx, as_index=False) 

# Need to set the index to match the result of groupby.size() 
df1 = df1.set_index(idx) 
df1['g_size'] = group_by.size() 

# find the rows in the top half of respective group 
top_half = (group_by.cumcount()/df1.g_size.values).values < 0.5 

# build new data frames 
top = df1.loc[top_half].drop('g_size', axis=1).reset_index() 
bot = df1.loc[~top_half].drop('g_size', axis=1).reset_index() 

テストコード:

print(df) 
print('-- top') 
print(top) 
print('-- bot') 
print(bot) 
print('--') 

ソート結果:

 Date LG Year 
0 2011-1-1 AR1 2011 
1 2011-3-1 AR1 2011 
2 2011-4-1 AR1 2011 
3 2011-2-1 AR1 2011 
4 2012-1-1 AR1 2012 
5 2012-2-1 AR1 2012 
6 2012-1-1 PO1 2012 
7 2012-2-1 PO1 2012 
8 2013-1-1 AR1 2013 
9 2013-2-1 AR1 2013 
10 2013-1-1 PO1 2013 
11 2013-2-1 PO1 2013 
-- top 
    Year LG  Date 
0 2011 AR1 2011-1-1 
1 2011 AR1 2011-2-1 
2 2012 AR1 2012-1-1 
3 2012 PO1 2012-1-1 
4 2013 AR1 2013-1-1 
5 2013 PO1 2013-1-1 
-- bot 
    Year LG  Date 
0 2011 AR1 2011-3-1 
1 2011 AR1 2011-4-1 
2 2012 AR1 2012-2-1 
3 2012 PO1 2012-2-1 
4 2013 AR1 2013-2-1 
5 2013 PO1 2013-2-1 

試験データ:

df = pd.DataFrame({ 
    'LG': ('AR1', 'AR1', 'AR1', 'AR1', 'AR1', 'AR1', 
      'PO1', 'PO1', 'AR1', 'AR1', 'PO1', 'PO1'), 
    'Date': ('2011-1-1', '2011-3-1', '2011-4-1', '2011-2-1', '2012-1-1', 
      '2012-2-1', '2012-1-1', '2012-2-1', '2013-1-1', '2013-2-1', 
      '2013-1-1', '2013-2-1'), 
    'Year': (2011, 2011, 2011, 2011, 2012, 2012, 2012, 2012, 2013, 
      2013, 2013, 2013) 
}) 
pd.to_datetime(df['Date']) 
+0

ありがとう、1つの問題。 2011年のAR1は正しく分割されていません。 2011-2-1はグループ「ボトム」、2011-3-1はグループトップです。どうして? – Zanshin

+0

ああ、それはソートしたいですか?あなたはサンプル出力を表示しなかったので、私は仮定しませんでした。私は何かを振ってみましょう... –

+0

ええ、私の悪い。私は日付のように年の最初の50%を意味し、示されているように列ではありません。しかし、ありがとう – Zanshin

関連する問題