2015-01-16 29 views
7

Tôi đã thấy rất nhiều bài viết về cách bạn có thể làm điều đó với một chuỗi ngày nhưng tôi đang cố gắng một cái gì đó cho một cột dataframe và đã không có bất kỳ may mắn cho đến nay. Phương pháp hiện tại của tôi là: Lấy ngày trong tuần từ 'myday' và sau đó bù đắp để có được thứ hai.Lấy ngày bắt đầu tuần (Thứ Hai) từ cột ngày bằng Python (gấu trúc)?

df['myday'] is column of dates. 
mydays = pd.DatetimeIndex(df['myday']).weekday 
df['week_start'] = pd.DatetimeIndex(df['myday']) - pd.DateOffset(days=mydays) 

Nhưng tôi nhận được Lỗi Loại: loại không được hỗ trợ cho ngày timedelta thành phần: numpy.ndarray

Làm thế nào tôi có thể nhận được trong tuần ngày bắt đầu từ một cột df?

Trả lời

1

không thành công vì pd.DateOffset mong đợi một số nguyên duy nhất làm tham số (và bạn đang cho nó một mảng). Bạn chỉ có thể sử dụng DateOffset để thay đổi cột ngày bằng cùng một giá trị bù trừ.

thử điều này:

import datetime as dt 
# Change 'myday' to contains dates as datetime objects 
df['myday'] = pd.to_datetime(df['myday']) 
# 'daysoffset' will container the weekday, as integers 
df['daysoffset'] = df['myday'].apply(lambda x: x.weekday()) 
# We apply, row by row (axis=1) a timedelta operation 
df['week_start'] = df.apply(lambda x: x['myday'] - dt.TimeDelta(days=x['mydays']), axis=1) 

tôi đã không thực sự kiểm tra mã này, (không có dữ liệu mẫu), nhưng điều đó sẽ làm việc cho những gì bạn đã mô tả.

Tuy nhiên, bạn có thể muốn xem pandas.Resample, có thể cung cấp giải pháp tốt hơn - tùy thuộc vào chính xác những gì bạn đang tìm kiếm.

+0

Cảm ơn bạn đã giải thích. Giải pháp này thực hiện chính xác những gì tôi muốn! – dev28

11

Một thay thế:

df['week_start'] = df['myday'].dt.to_period('W').apply(lambda r: r.start_time) 

này sẽ thiết lập 'week_start' là Thứ Hai đầu tiên trước thời điểm trong 'myday'.

4

Trong khi cả hai giải pháp trên hoạt động, tôi có xu hướng cố gắng tránh xa việc sử dụng áp dụng trong Pandas vì nó thường khá chậm so với phương pháp dựa trên mảng. Để tránh điều này, chúng tôi có thể sửa đổi phương thức dựa trên ngày trong tuần và chỉ cần bỏ ngày trong tuần là numpy timedelta64[D].

df['myday'] - df['myday'].dt.weekday.astype('timedelta64[D]') 

Sử dụng dữ liệu thử nghiệm của tôi với 60.000 datetimes tôi có những thời điểm sau bằng cách sử dụng hai câu trả lời gợi ý khác và đúc phương pháp dựa.

%timeit df.apply(lambda x: x['myday'] - datetime.timedelta(days=x['myday'].weekday()), axis=1) 
>>> 1 loop, best of 3: 7.43 s per loop 
%timeit df['myday'].dt.to_period('W').apply(lambda r: r.start_time) 
>>> 1 loop, best of 3: 2.38 s per loop 
%timeit df['myday'] - df['myday'].dt.weekday.astype('timedelta64[D]') 
>>> 100 loops, best of 3: 12.3 ms per loop 

hoặc gần 200 lần nhanh hơn trên tập dữ liệu của tôi.

+0

Tính năng này hoạt động như thế nào? df ['myday']. dt.weekday.astype ('timedelta64 [D]') trong tập dữ liệu của tôi trả về một chuỗi tất cả các số 0. Tại sao hoặc cách trừ 0 từ df ['myday'] hoạt động? Điều này có vẻ như giải pháp tốt nhất. –

+0

Làm rõ bài viết trên, cách tôi hiểu những gì đang xảy ra là về cơ bản nó là nói lấy ngày và sau đó trừ ngày trong tuần từ nó. Nhưng những gì tôi không hiểu là lý do tại sao .astype ('timedelta64 [D]') dẫn đến tất cả các số không. –

Các vấn đề liên quan