Pandas Datetime列から月と年だけを個別に抽出する


221

次の列のデータフレームdfがあります。

df['ArrivalDate'] =
...
936   2012-12-31
938   2012-12-29
965   2012-12-31
966   2012-12-31
967   2012-12-31
968   2012-12-31
969   2012-12-31
970   2012-12-29
971   2012-12-31
972   2012-12-29
973   2012-12-29
...

列の要素はpandas.tslib.Timestampです。

年と月だけを含めたい。簡単な方法があると思いましたが、わかりません。

これが私が試したものです:

df['ArrivalDate'].resample('M', how = 'mean')

次のエラーが発生しました:

Only valid with DatetimeIndex or PeriodIndex 

それから私は試しました:

df['ArrivalDate'].apply(lambda(x):x[:-2])

次のエラーが発生しました:

'Timestamp' object has no attribute '__getitem__' 

助言がありますか?

編集:私はそれをちょっと考え出した。

df.index = df['ArrivalDate']

次に、インデックスを使用して別の列をリサンプリングできます。

しかし、私はまだ列全体を再構成する方法が欲しいです。何か案は?


11
最良の答えは明らかに.. df ['mnth_yr'] = df.date_column.dt.to_period( 'M')from @ jaknap32
ihightower

1
あなたもする必要はありませんto_period:(df.date_column.dt.monthまたは.year、または.day)動作
elz


2
@elphz:.dt.month年を失います。そして.dt.to_period('M')、データ型をもうdatetime64ではないものに変更します。値を切り捨てることを提案するフアンの答えを使用してしまいました.astype('datetime64[M]')
ニコライ

ベストアンサーを変更できますか?
ゴンサロガルシア

回答:


306

年と月を別々に表示する新しい列が必要な場合は、次のようにすることができます。

df['year'] = pd.DatetimeIndex(df['ArrivalDate']).year
df['month'] = pd.DatetimeIndex(df['ArrivalDate']).month

または...

df['year'] = df['ArrivalDate'].dt.year
df['month'] = df['ArrivalDate'].dt.month

次に、それらを組み合わせたり、そのまま使用したりできます。


7
これを1行で行う方法はありますか?同じ列を複数回トラバースすることを避けたいです。
fixxxer 2015年

2
いくつかの簡単なベンチマークは、timeitことを示唆しているDatetimeIndexアプローチが大幅に高速化のいずれかよりもです.map/.apply.dt
Snorfalorpagus

2
最良の答えは明らかに.. df ['mnth_yr'] = df.date_column.dt.to_period( 'M')from @ jaknap32
ihightower

実際にpd.Datetimeindexは何をしますか?
ジョン

私は時々これを行います: df['date_column_trunc'] = df[date_column'].apply(lambda s: datetime.date(s.year, s.month, 1)
Stewbaca

229

最高の方法が見つかりました !!

df['date_column']は日時形式でなければなりません。

df['month_year'] = df['date_column'].dt.to_period('M')

さまざまなサンプリング間隔で1 D日、2M2か月などを使用することもできます。タイムスタンプ付きの時系列データがある場合45Min、45分間、15Min15分間のサンプリングなど、細かいサンプリング間隔を使用できます。


8
結果の列がdatetime64dtypeではなくなったことに注意してください。@Juanの回答のdf.my_date_column.astype('datetime64[M]')ように、を使用すると、各月の最初の日を表す日付に変換されます。
ニコライ

3
。私は"mが、これがダウンし、ここですべての方法で驚い
ティム・

154

yearmonth属性に直接アクセスするか、をリクエストできますdatetime.datetime

In [15]: t = pandas.tslib.Timestamp.now()

In [16]: t
Out[16]: Timestamp('2014-08-05 14:49:39.643701', tz=None)

In [17]: t.to_pydatetime() #datetime method is deprecated
Out[17]: datetime.datetime(2014, 8, 5, 14, 49, 39, 643701)

In [18]: t.day
Out[18]: 5

In [19]: t.month
Out[19]: 8

In [20]: t.year
Out[20]: 2014

年と月を組み合わせる1つの方法は、次のように整数をエンコードすることです201408。2014年8月の場合。列全体で、次のように実行できます。

df['YearMonth'] = df['ArrivalDate'].map(lambda x: 100*x.year + x.month)

またはその多くの変種。

ただし、これを行うのはあまり好きではありません。これは、日付の調整と計算が後で苦痛になり、特にこの同じ規則なしにコードやデータにアクセスする他の人にとって苦痛になるためです。より良い方法は、最終的な非US休日の平日、または初日などの月の日付の規則を選択し、選択した日付の規則で日付/時刻形式のままにすることです。

このcalendarモジュールは、最終的な平日など、特定の日の数値を取得するのに役立ちます。それからあなたは次のようなことをすることができます:

import calendar
import datetime
df['AdjustedDateToEndOfMonth'] = df['ArrivalDate'].map(
    lambda x: datetime.datetime(
        x.year,
        x.month,
        max(calendar.monthcalendar(x.year, x.month)[-1][:5])
    )
)

日時列を文字列化された表現にフォーマットするという単純な問題を解決する方法を探している場合は、次のようにクラスのstrftime関数を使用できますdatetime.datetime

In [5]: df
Out[5]: 
            date_time
0 2014-10-17 22:00:03

In [6]: df.date_time
Out[6]: 
0   2014-10-17 22:00:03
Name: date_time, dtype: datetime64[ns]

In [7]: df.date_time.map(lambda x: x.strftime('%Y-%m-%d'))
Out[7]: 
0    2014-10-17
Name: date_time, dtype: object

4
パフォーマンスが低下する可能性があるため、ヘルパー関数、ベクトル化された操作、およびpandas分割-適用-結合の手法を最大限に活用することは常に良いことです。上記の私の提案は、それらがあなたのケースにとって最もパフォーマンスの高いアプローチであるという推奨を意味するものではありません-単にそれらが幅広いケースに対してスタイル的に有効なPythonicの選択であるということです。
2014

@KieranPCによる以下の回答は、はるかに高速です
ベン

2
最良の答えは明らかに.. df ['mnth_yr'] = df.date_column.dt.to_period( 'M')from @ jaknap32
ihightower

2
では、100倍することになっていますdf['YearMonth'] = df['ArrivalDate'].map(lambda x: 1000*x.year + x.month)
Git Gud

1
@ zthomas.nc彼らはそれを解決するために2つの非常に異なる方法を提供するので、私はそれらが2つの別々の答えとしてよりよく機能すると思います。
-e

34

月と年の一意のペアが必要な場合は、applyを使用するとかなりスマートになります。

df['mnth_yr'] = df['date_column'].apply(lambda x: x.strftime('%B-%Y')) 

1つの列に月と年を出力します。

最初にフォーマットを日付時刻に変更することを忘れないでください。

df['date_column'] = pd.to_datetime(df['date_column'])

あなたにもラムダ関数を避けることができます:df['month_year'] = df['date_column'].dt.strftime('%B-%Y')
Rishabh

13

['2018-03-04']から年を抽出する

df['Year'] = pd.DatetimeIndex(df['date']).year  

df ['Year']は新しい列を作成します。一方、月を抽出する場合は、.monthを使用します


1
おかげで、本当に役に立ちましたdate_1 = pd.DatetimeIndex(df ['date'])--year = date_1.year#年の場合---month = date_1.month#月の場合---dy = date_1。 day#for days--
エドウィントーレ​​ス

7

最初にpandas.to_datetimeを使用して日付文字列を変換できます。これにより、numpyのすべてのdatetimeおよびtimedelta機能にアクセスできます。例えば:

df['ArrivalDate'] = pandas.to_datetime(df['ArrivalDate'])
df['Month'] = df['ArrivalDate'].values.astype('datetime64[M]')

pysparkに類似した機能を探していたので、これは私にとって本当にうまくいきましたtruncastype('datetime64[M]')大会に関する文書はありますか?
h1-the-swan


6

@KieranPCのソリューションはPandasにとって正しいアプローチですが、任意の属性に対して簡単に拡張することはできません。このためgetattrに、ジェネレータ内包で使用し、以下を使用して組み合わせることができますpd.concat

# input data
list_of_dates = ['2012-12-31', '2012-12-29', '2012-12-30']
df = pd.DataFrame({'ArrivalDate': pd.to_datetime(list_of_dates)})

# define list of attributes required    
L = ['year', 'month', 'day', 'dayofweek', 'dayofyear', 'weekofyear', 'quarter']

# define generator expression of series, one for each attribute
date_gen = (getattr(df['ArrivalDate'].dt, i).rename(i) for i in L)

# concatenate results and join to original dataframe
df = df.join(pd.concat(date_gen, axis=1))

print(df)

  ArrivalDate  year  month  day  dayofweek  dayofyear  weekofyear  quarter
0  2012-12-31  2012     12   31          0        366           1        4
1  2012-12-29  2012     12   29          5        364          52        4
2  2012-12-30  2012     12   30          6        365          52        4

1
df['year_month']=df.datetime_column.apply(lambda x: str(x)[:7])

これは私にとってはうまくいきました、パンダが結果の文字列の日付を日付として解釈するとは思っていませんでしたが、私がプロットを行ったとき、それは私のアジェンダと適切に注文された文字列year_monthをよく知っていました...パンダが大好きです!


1

メソッドの適用を使用せずにすべてのデータフレームの年を抽出するには、2つのステップがあります。

ステップ1

列をdatetimeに変換します。

df['ArrivalDate']=pd.to_datetime(df['ArrivalDate'], format='%Y-%m-%d')

ステップ2

DatetimeIndex()メソッドを使用して年または月を抽出する

 pd.DatetimeIndex(df['ArrivalDate']).year

1

単一行: 'year-month'-pairesを使用した列の追加:( ' pd.to_datetime 'は、操作の前に最初に列のdtypeをdate-timeに変更します)

df['yyyy-mm'] = pd.to_datetime(df['ArrivalDate']).dt.strftime('%Y-%m')

したがって、追加の「年」または「月」列の場合:

df['yyyy'] = pd.to_datetime(df['ArrivalDate']).dt.strftime('%Y')

df['mm'] = pd.to_datetime(df['ArrivalDate']).dt.strftime('%m')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.