web-dev-qa-db-ja.com

pandas日時月ごとのデータフレームグループ

Csvファイルを考えます:

string,date,number
a string,2/5/11 9:16am,1.0
a string,3/5/11 10:44pm,2.0
a string,4/22/11 12:07pm,3.0
a string,4/22/11 12:10pm,4.0
a string,4/29/11 11:59am,1.0
a string,5/2/11 1:41pm,2.0
a string,5/2/11 2:02pm,3.0
a string,5/2/11 2:56pm,4.0
a string,5/2/11 3:00pm,5.0
a string,5/2/14 3:02pm,6.0
a string,5/2/14 3:18pm,7.0

これを読み取り、日付列を日時形式に再フォーマットできます。

b=pd.read_csv('b.dat')
b['date']=pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')

月ごとにデータをグループ化しようとしています。月にアクセスし、それによってグループ化する明らかな方法があるはずです。しかし、私はそれをすることができないようです。誰もが方法を知っていますか?

私が現在試しているのは、日付までにインデックスを再作成することです:

b.index=b['date']

次のように月にアクセスできます:

b.index.month

しかし、月ごとにひとまとめにする関数を見つけることはできません。

64
atomh33ls

それを行うことができました:

b=pd.read_csv('b.dat')
b.groupby(by=[b.index.month, b.index.year])

または

b.groupby(pd.Grouper(freq='M'))  # update for v0.21+
124
atomh33ls

(更新:2018)

pd.Timegrouperは減価償却され、削除されることに注意してください。代わりに使用します:

 df.groupby(pd.Grouper(freq='M'))
48
PandasRocks

MultiIndexを回避する1つの解決策は、新しいdatetime列を作成し、日を1に設定することです。次に、この列でグループ化します。以下の簡単な例。

df = pd.DataFrame({'Date': pd.to_datetime(['2017-10-05', '2017-10-20']),
                   'Values': [5, 10]})

# normalize day to beginning of month
df['YearMonth'] = df['Date'] + pd.offsets.MonthBegin(1)

# two alternative methods
df['YearMonth'] = df['Date'] - pd.to_timedelta(df['Date'].dt.day-1, unit='D')
df['YearMonth'] = df['Date'].map(lambda dt: dt.replace(day=1))

g = df.groupby('YearMonth')

res = g['Values'].sum()

# YearMonth
# 2017-10-01    15
# Name: Values, dtype: int64

このソリューションの微妙な利点は、pd.Grouperとは異なり、グルーパーインデックスが各月の終わりではなくbeginningに正規化されるため、簡単にできることです。 get_groupを介してグループを抽出します。

some_group = g.get_group('2017-10-01')

10月の最終日を計算するのは少し面倒です。 pd.Grouper 、v0.23現在、conventionパラメーターをサポートしていますが、これはPeriodIndex grouperにのみ適用可能です。

5
jpp

@jppの少し代替ソリューションですが、YearMonth文字列を出力します。

df['YearMonth'] = pd.to_datetime(df['Date']).apply(lambda x: '{year}-{month}'.format(year=x.year, month=x.month))

res = df.groupby('YearMonth')['Values'].sum()
3
tsando