You can use the function tz_localize to make a Timestamp or DateTimeIndex timezone aware, but how can you do the opposite: how can you convert a timezone aware Timestamp to a naive one, while preserving its timezone?

Is there another way I can convert a DateTimeIndex to timezone naive, but while preserving the timezone it was set in?

Some context on the reason I am asking this: I want to work with timezone naive timeseries (to avoid the extra hassle with timezones, and I do not need them for the case I am working on).
But for some reason, I have to deal with a timezone-aware timeseries in my local timezone (Europe/Brussels). As all my other data are timezone naive (but represented in my local timezone), I want to convert this timeseries to naive to further work with it, but it also has to be represented in my local timezone (so just remove the timezone info, without converting the user-visible time to UTC).

I know the time is actually internal stored as UTC and only converted to another timezone when you represent it, so there has to be some kind of conversion when I want to "delocalize" it. For example, with the python datetime module you can "remove" the timezone like this:

In case you're working with something that's already UTC and need to convert it to local time and then drop the timezone: from tzlocal import get_localzone, tz_here = get_localzone(), <datetime object>.tz_convert(tz_here).tz_localize(None)
– Nathan LloydNov 3 '16 at 23:29

If you don't have a useful index, you may need t.dt.tz_localize(None) or t.dt.tz_convert(None). Note the .dt.
– A-B-BOct 27 '18 at 22:22

I think you can't achieve what you want in a more efficient manner than you proposed.

The underlying problem is that the timestamps (as you seem aware) are made up of two parts. The data that represents the UTC time, and the timezone, tz_info. The timezone information is used only for display purposes when printing the timezone to the screen. At display time, the data is offset appropriately and +01:00 (or similar) is added to the string. Stripping off the tz_info value (using tz_convert(tz=None)) doesn't doesn't actually change the data that represents the naive part of the timestamp.

So, the only way to do what you want is to modify the underlying data (pandas doesn't allow this... DatetimeIndex are immutable -- see the help on DatetimeIndex), or to create a new set of timestamp objects and wrap them in a new DatetimeIndex. Your solution does the latter:

pd.DatetimeIndex([i.replace(tzinfo=None) for i in t])

For reference, here is the replace method of Timestamp (see tslib.pyx):

You can refer to the docs on datetime.datetime to see that datetime.datetime.replace also creates a new object.

If you can, your best bet for efficiency is to modify the source of the data so that it (incorrectly) reports the timestamps without their timezone. You mentioned:

I want to work with timezone naive timeseries (to avoid the extra hassle with timezones, and I do not need them for the case I am working on)

I'd be curious what extra hassle you are referring to. I recommend as a general rule for all software development, keep your timestamp 'naive values' in UTC. There is little worse than looking at two different int64 values wondering which timezone they belong to. If you always, always, always use UTC for the internal storage, then you will avoid countless headaches. My mantra is Timezones are for human I/O only.

Thanks for the answer, and a late reply: my case is not an application, just a scientific analysis for my own work (so eg no sharing with collaborators over the world). And in that case, it can be easier to just work with naive timestamps, but in your local time. So I don't have to worry about time zones and just can interprete the timestamp as local time (the extra 'hassle' can be eg that everything then has to be in timezones, otherwise you get things like "can't compare offset-naive and offset-aware datetimes"). But I completely agree with you when dealing with more complex applications.
– jorisDec 21 '13 at 13:22

Late comment, but I want the result to be the time represented in the local time zone, not in UTC. And as I show in the question, setting the tz to None also converts it to UTC.
– jorisJan 8 '16 at 22:31

Further, the timeseries is already timezone aware, so calling tz_convert on it will raise an error.
– jorisJan 8 '16 at 22:32