tz-aware datetime系列在pandas series apply(lambda)操作中产生基于UTC的.date()输出

时间:2015-12-03 23:34:51

标签: python datetime pandas pytz timestamp-with-timezone

我在Python 2.7 / pandas 0.17.1中使用Unix时间戳,需要生成一系列本地日期(在美国东部时间)。在单个数据点上调用.date()时,时区感知标记似乎按预期工作(给出本地日期),但是当它们作为系列工作时,它们似乎恢复为UTC日期。有没有办法让基于系列的日期输出与在对象上单独调用.date()生成的本地日期相匹配? (谢谢!)

def stamp_converter(ts):
    ser = pd.to_datetime(ts, unit='s', utc=True)
    ind = pd.DatetimeIndex(ser).tz_localize('UTC').tz_convert('US/Eastern')
    return ind

test_stamps = pd.Series([1396670200, 1405733045, 1448248441])  
# e.g., 4/05 in GMT, 4/04 in Eastern

local_dates = pd.Series(stamp_converter(test_stamp))

print local_dates

# 0   2014-04-04 23:56:40-04:00
# 1   2014-07-18 21:24:05-04:00
# 2   2015-11-22 22:14:01-05:00
# dtype: datetime64[ns, US/Eastern]

print local_dates.apply(lambda x: x.date())

# 0    2014-04-05
# 1    2014-07-19
# 2    2015-11-23
# dtype: object

for i, x in local_dates.iteritems():
    print x.date()

# 2014-04-04
# 2014-07-18
# 2015-11-22

1 个答案:

答案 0 :(得分:0)

糟糕。找到了。

var isMdown     = false,    // gets set to true when user clicks the handle
    isToggled = false,  // gets set to true when user clicks the bar or handle
    progress    = $('#progress'),
    percentage= null,   // keeps track of the last % 
    handleW     = 8,            // width of the handle, req. for positioning
    handle      = document.getElementById('slider-handle'),
    range       = document.getElementById('slider-range');

// main position adjustment function
var setPos = function(e) {
  var posxBuffer = e.clientX - progress.offset().left,
      w = this.clientWidth;
  widget.getDuration(function(duration){
    widget.seekTo(percentage*duration/100);
    handle.style.left = percentage + '%';
    range.style.width = percentage + '%';
  });
  isToggled = false;
  isMdown   = false;
};

// we just need to update the % value here and set some flags
progress.on('mousedown', function(e) {
  isToggled = true;
  var posxBuffer = e.clientX - progress.offset().left,
      w = this.clientWidth;
  percentage = ((posxBuffer-handleW)*100)/w;
  if (e.target === handle)
    isMdown = true;
});

progress.on('mouseover', function(e) {
  // if the user has previously triggered a mousedown event, he is now dragging
  // => adjust handle position, but not time progress
  if (isMdown) {
    var posxBuffer = e.clientX- progress.offset().left,
        w = this.clientWidth;
    percentage = ((posxBuffer-handleW)*100)/w;
    handle.style.left = percentage + '%';
    range.style.width = percentage + '%';
  }
});

// when a user has clicked the progress bar and releases the button,
// set the position
progress.on('mouseup', setPos);

// when a user is still dragging but leaves the progress bar, 
// release and set to last position
progress.on('mouseleave', function(e) {
  if (isMdown)
    setPos(e);
});

widget.bind(SC.Widget.Events.PLAY_PROGRESS, function(){
  widget.getPosition(function(position){
    widget.getDuration(function(duration){
       $('#seekms').text(duration);  
       // Just as a bonus, the code for transforming ms into a MM:SS format =)
       var mins = (position/1000/60 < 10 ? '0' : '') + Math.floor(position/1000/60),
           secs = (position/1000%60 < 10 ? '0' : '') + Math.floor((position/1000) %60);
       $('#bufferms').text(mins + ':' + secs);
       // only updated if the user already moused down on either handler or bar
       if (isToggled || isMdown)
          return;
       var percentage = position*100/duration;
       $("#slider-range").css("width", percentage + '%');
       $("#slider-handle").css("left", percentage + '%');
                 $('#inputseek').val(percentage);
    });
  });
});

尽管如此:令人费解的是,各个.date()操作和.apply(lambda x:x.date())之间的行为有所不同。如果有人能解释为什么会这样,我感兴趣。