草庐IT

python - 更改 pandas datetime64 列的时间组件

coder 2023-08-18 原文

我有一个可以简化为的数据框:

                date  id
0   02/04/2015 02:34   1
1   06/04/2015 12:34   2
2   09/04/2015 23:03   3
3   12/04/2015 01:00   4
4   15/04/2015 07:12   5
5   21/04/2015 12:59   6
6   29/04/2015 17:33   7
7   04/05/2015 10:44   8
8   06/05/2015 11:12   9
9   10/05/2015 08:52  10
10  12/05/2015 14:19  11
11  19/05/2015 19:22  12
12  27/05/2015 22:31  13
13  01/06/2015 11:09  14
14  04/06/2015 12:57  15
15  10/06/2015 04:00  16
16  15/06/2015 03:23  17
17  19/06/2015 05:37  18
18  23/06/2015 13:41  19
19  27/06/2015 15:43  20

它可以通过以下方式创建:

tempDF = pd.DataFrame({ 'id': [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
                        'date': ["02/04/2015 02:34","06/04/2015 12:34","09/04/2015 23:03","12/04/2015 01:00","15/04/2015 07:12","21/04/2015 12:59","29/04/2015 17:33","04/05/2015 10:44","06/05/2015 11:12","10/05/2015 08:52","12/05/2015 14:19","19/05/2015 19:22","27/05/2015 22:31","01/06/2015 11:09","04/06/2015 12:57","10/06/2015 04:00","15/06/2015 03:23","19/06/2015 05:37","23/06/2015 13:41","27/06/2015 15:43"]})

数据有以下几种类型:

tempDF.dtypes
date     object
id        int64
dtype: object

我已将“日期”变量设置为 Pandas datefime64 格式(如果这是描述它的正确方法)使用:

import numpy as np
import pandas as pd
tempDF['date'] = pd_to_datetime(tempDF['date'])

现在,数据类型看起来像:

tempDF.dtypes
date     datetime64[ns]
id                int64
dtype: object

我想更改原始日期数据的小时数。我可以使用 .normalize() 通过 .dt 访问器转换为午夜:

tempDF['date'] = tempDF['date'].dt.normalize()

而且,我可以使用以下方式访问各个日期时间组件(例如年份):

tempDF['date'].dt.year

这会产生:

0     2015
1     2015
2     2015
3     2015
4     2015
5     2015
6     2015
7     2015
8     2015
9     2015
10    2015
11    2015
12    2015
13    2015
14    2015
15    2015
16    2015
17    2015
18    2015
19    2015
Name: date, dtype: int64

问题是,如何更改特定的日期和时间组件?例如,如何更改所有日期的中午 ​​(12:00)?我发现 datetime.datetime 有一个 .replace() 函数。但是,将日期转换为 Pandas 格式后,保留该格式是有意义的。有没有办法在不再次更改格式的情况下做到这一点?

最佳答案

编辑:

执行此操作的矢量化方法是规范化系列,然后使用 timedelta 添加 12 小时。示例 -

tempDF['date'].dt.normalize() + datetime.timedelta(hours=12)

演示 -

In [59]: tempDF
Out[59]:
                  date  id
0  2015-02-04 12:00:00   1
1  2015-06-04 12:00:00   2
2  2015-09-04 12:00:00   3
3  2015-12-04 12:00:00   4
4  2015-04-15 12:00:00   5
5  2015-04-21 12:00:00   6
6  2015-04-29 12:00:00   7
7  2015-04-05 12:00:00   8
8  2015-06-05 12:00:00   9
9  2015-10-05 12:00:00  10
10 2015-12-05 12:00:00  11
11 2015-05-19 12:00:00  12
12 2015-05-27 12:00:00  13
13 2015-01-06 12:00:00  14
14 2015-04-06 12:00:00  15
15 2015-10-06 12:00:00  16
16 2015-06-15 12:00:00  17
17 2015-06-19 12:00:00  18
18 2015-06-23 12:00:00  19
19 2015-06-27 12:00:00  20

In [60]: tempDF['date'].dt.normalize() + datetime.timedelta(hours=12)
Out[60]:
0    2015-02-04 12:00:00
1    2015-06-04 12:00:00
2    2015-09-04 12:00:00
3    2015-12-04 12:00:00
4    2015-04-15 12:00:00
5    2015-04-21 12:00:00
6    2015-04-29 12:00:00
7    2015-04-05 12:00:00
8    2015-06-05 12:00:00
9    2015-10-05 12:00:00
10   2015-12-05 12:00:00
11   2015-05-19 12:00:00
12   2015-05-27 12:00:00
13   2015-01-06 12:00:00
14   2015-04-06 12:00:00
15   2015-10-06 12:00:00
16   2015-06-15 12:00:00
17   2015-06-19 12:00:00
18   2015-06-23 12:00:00
19   2015-06-27 12:00:00
dtype: datetime64[ns]

底部两种方法的时间信息


一种方法是使用 Series.apply连同 .replace()方法 OP 在他的帖子中提到。示例 -

tempDF['date'] = tempDF['date'].apply(lambda x:x.replace(hour=12,minute=0))

演示 -

In [12]: tempDF
Out[12]:
                  date  id
0  2015-02-04 02:34:00   1
1  2015-06-04 12:34:00   2
2  2015-09-04 23:03:00   3
3  2015-12-04 01:00:00   4
4  2015-04-15 07:12:00   5
5  2015-04-21 12:59:00   6
6  2015-04-29 17:33:00   7
7  2015-04-05 10:44:00   8
8  2015-06-05 11:12:00   9
9  2015-10-05 08:52:00  10
10 2015-12-05 14:19:00  11
11 2015-05-19 19:22:00  12
12 2015-05-27 22:31:00  13
13 2015-01-06 11:09:00  14
14 2015-04-06 12:57:00  15
15 2015-10-06 04:00:00  16
16 2015-06-15 03:23:00  17
17 2015-06-19 05:37:00  18
18 2015-06-23 13:41:00  19
19 2015-06-27 15:43:00  20

In [13]: tempDF['date'] = tempDF['date'].apply(lambda x:x.replace(hour=12,minute=0))

In [14]: tempDF
Out[14]:
                  date  id
0  2015-02-04 12:00:00   1
1  2015-06-04 12:00:00   2
2  2015-09-04 12:00:00   3
3  2015-12-04 12:00:00   4
4  2015-04-15 12:00:00   5
5  2015-04-21 12:00:00   6
6  2015-04-29 12:00:00   7
7  2015-04-05 12:00:00   8
8  2015-06-05 12:00:00   9
9  2015-10-05 12:00:00  10
10 2015-12-05 12:00:00  11
11 2015-05-19 12:00:00  12
12 2015-05-27 12:00:00  13
13 2015-01-06 12:00:00  14
14 2015-04-06 12:00:00  15
15 2015-10-06 12:00:00  16
16 2015-06-15 12:00:00  17
17 2015-06-19 12:00:00  18
18 2015-06-23 12:00:00  19
19 2015-06-27 12:00:00  20

时间信息

In [52]: df = pd.DataFrame([[datetime.datetime.now()] for _ in range(100000)],columns=['date'])

In [54]: %%timeit
   ....: df['date'].dt.normalize() + datetime.timedelta(hours=12)
   ....:
The slowest run took 12.53 times longer than the fastest. This could mean that an intermediate result is being cached
1 loops, best of 3: 32.3 ms per loop

In [57]: %%timeit
   ....: df['date'].apply(lambda x:x.replace(hour=12,minute=0))
   ....:
1 loops, best of 3: 1.09 s per loop

关于python - 更改 pandas datetime64 列的时间组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33362697/

有关python - 更改 pandas datetime64 列的时间组件的更多相关文章

  1. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  6. ruby - Capistrano 3 在任务中更改 ssh_options - 2

    我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

  7. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  8. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  9. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  10. ruby - 更改 ActiveRecord 中对象的类 - 2

    假设我有一个FireNinja我的数据库中的对象,使用单表继承存储。后来才知道他真的是WaterNinja.将他更改为不同的子类的最干净的方法是什么?更好的是,我很想创建一个新的WaterNinja对象并替换旧的FireNinja在数据库中,保留ID。编辑我知道如何创建新的WaterNinja来self现有FireNinja的对象,我也知道我可以删除旧的并保存新的。我想做的是改变现有项目的类别。我是通过创建一个新对象并执行一些ActiveRecord魔法来替换行,还是通过对对象本身做一些疯狂的事情,或者甚至通过删除它并使用相同的ID重新插入来做到这一点,这是问题的一部分。

随机推荐