Làm cách nào để chuyển đổi ngày tháng trong khung dữ liệu Pandas thành kiểu dữ liệu 'ngày tháng'?


103

Tôi có một khung dữ liệu Pandas, một trong các cột chứa các chuỗi ngày ở định dạng YYYY-MM-DD

Ví dụ '2013-10-28'

Tại thời điểm này dtype, cột là object.

Làm cách nào để chuyển đổi các giá trị cột sang định dạng ngày tháng Pandas?

Câu trả lời:


108

Sử dụng astype

In [31]: df
Out[31]: 
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [32]: df['time'] = df['time'].astype('datetime64[ns]')

In [33]: df
Out[33]: 
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00

1
Rất vui - cảm ơn bạn - làm cách nào để thoát khỏi 00:00:00 vào cuối mỗi buổi hẹn hò?
user7289,

1
Dấu thời gian của gấu trúc có cả ngày và giờ. Bạn có nghĩa là chuyển đổi nó thành đối tượng ngày python?
Waitkuo,

6
Bạn có thể chuyển đổi nó bằng cáchdf['time'] = [time.date() for time in df['time']]
waitkuo,

3
[ns] có nghĩa là gì, bạn có thể đặt chuỗi văn bản thành ngày tháng và xóa phần thời gian của ngày đó không?
yoshiserry

1
@yoshiserry nó là nano giây và là cách ngày được lưu trữ dưới mui xe sau khi được chuyển đổi đúng cách (epoch-time tính bằng nano giây).
Andy Hayden

111

Về cơ bản tương đương với @waitingkuo, nhưng tôi sẽ sử dụng to_datetimeở đây (nó có vẻ gọn gàng hơn một chút và cung cấp một số chức năng bổ sung, ví dụ dayfirst):

In [11]: df
Out[11]:
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [12]: pd.to_datetime(df['time'])
Out[12]:
0   2013-01-01 00:00:00
1   2013-01-02 00:00:00
2   2013-01-03 00:00:00
Name: time, dtype: datetime64[ns]

In [13]: df['time'] = pd.to_datetime(df['time'])

In [14]: df
Out[14]:
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00

Xử lý ValueErrors
Nếu bạn gặp phải tình huống làm

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

Ném một

ValueError: Unknown string format

Điều đó có nghĩa là bạn có các giá trị không hợp lệ (không thể cưỡng chế). Nếu bạn đồng ý với việc chuyển đổi chúng thành pd.NaT, bạn có thể thêm errors='coerce'đối số vào to_datetime:

df['time'] = pd.to_datetime(df['time'], errors='coerce')

Xin chào các bạn, @AndyHayden bạn có thể xóa phần thời gian khỏi ngày không? Tôi không cần phần đó?
yoshiserry

Trong pandas '0.13.1, 00: 00: 00 ở cuối không được hiển thị.
Andy Hayden

và trong các phiên bản khác thì sao, làm cách nào để loại bỏ / và không hiển thị chúng?
yoshiserry

Tôi không nghĩ rằng điều này có thể được thực hiện một cách tốt đẹp, có một cuộc thảo luận để thêm date_format như float_format (mà bạn đã thấy). Tôi khuyên bạn nên nâng cấp bằng mọi cách.
Andy Hayden

vấn đề của tôi là ngày của tôi ở định dạng này ... 41516.43 và tôi gặp lỗi này. Tôi mong đợi nó sẽ trả về một cái gì đó giống như 2014-02-03 trong cột mới ?! LỖI: #convert các giá trị ngày trong cột "load_date" thành ngày budget_dataset ['date_last_load'] = pd.to_datetime (Budget_dataset ['load_date']) Budget_dataset -c: 2: SettingWithCopyWarning: Một giá trị đang cố gắng được đặt trên bản sao của một lát từ DataFrame. Thay vào đó, hãy thử sử dụng .loc [row_index, col_indexer] = value
yoshiserry Ngày

35

Tôi tưởng tượng rất nhiều dữ liệu được đưa vào Pandas từ tệp CSV, trong trường hợp đó bạn có thể chỉ cần chuyển đổi ngày trong lần đọc CSV ban đầu:

dfcsv = pd.read_csv('xyz.csv', parse_dates=[0])trong đó số 0 đề cập đến cột ngày tháng.
Bạn cũng có thể thêm , index_col=0vào đó nếu bạn muốn ngày làm chỉ mục của mình.

Xem https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html


Cảm ơn, đó chính xác là những gì tôi cần. Tuy nhiên, tài liệu đã được chuyển đi, bạn có thể tìm thấy nó ở đây: pandas.pydata.org/pandas-docs/stable/reference/api/…
Sastibe vào

24

Bây giờ bạn có thể làm df['column'].dt.date

Lưu ý rằng đối với các đối tượng datetime, nếu bạn không thấy giờ khi tất cả chúng đều là 00:00:00 thì đó không phải là gấu trúc. Đó là máy tính xách tay iPython đang cố gắng làm cho mọi thứ trông đẹp đẽ.


2
Cái này không hoạt động với tôi, nó phàn nàn: Chỉ có thể sử dụng trình truy cập .dt với các giá trị
giống

2
bạn có thể phải làm df[col] = pd.to_datetime(df[col])trước tiên để chuyển đổi cột của mình thành các đối tượng thời gian ngày tháng.
szeitlin

Vấn đề với câu trả lời này là nó chuyển đổi cột dtype = objectchiếm nhiều bộ nhớ hơn đáng kể so với cột đúng datetime dtypeở gấu trúc.
elPastor

6

Một cách khác để làm điều này và điều này hoạt động tốt nếu bạn có nhiều cột để chuyển đổi sang ngày giờ.

cols = ['date1','date2']
df[cols] = df[cols].apply(pd.to_datetime)

Câu hỏi yêu cầu ngày không phải ngày giờ.
Mark Andersen

@MarkAndersen miễn là bạn datechỉ có giá trị trong các cột của mình, việc chuyển đổi sang datetime sẽ chỉ giữ lại thông tin liên quan. Nếu bạn chuyển đổi rõ ràng bằng cách sử dụng df['datetime_col'].dt.datesẽ dẫn đến một loại objectdtype; mất quản lý bộ nhớ.
Sumanth Lazarus

5

Nếu bạn muốn nhận định dạng DATE chứ không phải DATETIME:

df["id_date"] = pd.to_datetime(df["id_date"]).dt.date

1

Có thể có trường hợp ngày tháng cần được chuyển đổi sang một tần số khác. Trong trường hợp này, tôi khuyên bạn nên đặt chỉ mục theo ngày.

#set an index by dates
df.set_index(['time'], drop=True, inplace=True)

Sau đó, bạn có thể dễ dàng chuyển đổi sang loại định dạng ngày tháng mà bạn cần nhất. Dưới đây, tôi chuyển đổi tuần tự sang một số định dạng ngày, cuối cùng kết thúc bằng một bộ ngày hàng ngày vào đầu tháng.

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

#Convert to monthly dates
df.index = df.index.to_period(freq='M')

#Convert to strings
df.index = df.index.strftime('%Y-%m')

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

Để ngắn gọn, tôi không cho thấy rằng tôi chạy mã sau sau mỗi dòng ở trên:

print(df.index)
print(df.index.dtype)
print(type(df.index))

Điều này cho tôi kết quả sau:

Index(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='object', name='time')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='datetime64[ns]', name='time', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

PeriodIndex(['2013-01', '2013-01', '2013-01'], dtype='period[M]', name='time', freq='M')
period[M]
<class 'pandas.core.indexes.period.PeriodIndex'>

Index(['2013-01', '2013-01', '2013-01'], dtype='object')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-01', '2013-01-01'], dtype='datetime64[ns]', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

0

Cố gắng chuyển đổi một trong các hàng thành dấu thời gian bằng cách sử dụng hàm pd.to_datetime và sau đó sử dụng .map để ánh xạ biểu mẫu cho toàn bộ cột


0
 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  object
 1   endDay          110526 non-null  object

import pandas as pd

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

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

 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  datetime64[ns]
 1   endDay          110526 non-null  datetime64[ns]

0

Để hoàn thiện, một tùy chọn khác, có thể không phải là lựa chọn đơn giản nhất, hơi giống với tùy chọn được đề xuất bởi @SSS, nhưng sử dụng thư viện datetime là:

import datetime
df["Date"] = df["Date"].apply(lambda x: datetime.datetime.strptime(x, '%Y-%d-%m').date())
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.